diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1a39cfa..dcadb51d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: [push] jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout Code uses: actions/checkout@v4 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9189c38b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: cpp - -# NOTE: Since we do not have direct access to either MacOS or Windows -# machines on which to develop WE DO NOT support building on MacOS or -# Windows. - -# For Windows, it is known that the more recent Windows 10 versions are -# able to use either the debian archive OR AppImage (as Windows 10 now -# allows FUSE). - -compiler: gcc - -branches: - except: # do not build tags that we create using the upload.sh script - - /^(?i:continuous.*)$/ - -jobs: - fast_finish: true - include: - - os: linux - dist: bionic - env: CONTAINER_FROM="ubuntu:18.04" - services: - - docker - addons: - firefox: latest - script: - - ./buildScripts/travisLinuxDoItAll diff --git a/buildScripts/buildPdf2htmlEX b/buildScripts/buildPdf2htmlEX index e5452b62..9759fd8a 100755 --- a/buildScripts/buildPdf2htmlEX +++ b/buildScripts/buildPdf2htmlEX @@ -20,4 +20,4 @@ rm -rf build mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PDF2HTMLEX_PREFIX .. -make $MAKE_PARALLEL +make $MAKE_PARALLEL VERBOSE=1 diff --git a/buildScripts/versionEnvs b/buildScripts/versionEnvs index 9ef5f8b7..2d454041 100755 --- a/buildScripts/versionEnvs +++ b/buildScripts/versionEnvs @@ -3,12 +3,13 @@ # This shell script exports environment variables for the latest software # versions -# see: https://poppler.freedesktop.org/releases.html -# current working: 24.06.1 - export PDF2HTMLEX_VERSION=0.18.8.rc2 -export POPPLER_VERSION=poppler-24.06.1 +# see: https://poppler.freedesktop.org/releases.html +# current working: 26.05.0 + +export POPPLER_VERSION=poppler-26.05.0 +#export POPPLER_VERSION=poppler-24.06.1 #export POPPLER_VERSION=poppler-24.01.0 #export POPPLER_VERSION=poppler-23.12.0 #export POPPLER_VERSION=poppler-21.02.0 @@ -26,6 +27,7 @@ export POPPLER_VERSION=poppler-24.06.1 # see: https://github.com/fontforge/fontforge/releases # current working: 20230101 +#export FONTFORGE_VERSION=20251009 export FONTFORGE_VERSION=20230101 #export FONTFORGE_VERSION=20220308 #export FONTFORGE_VERSION=20190801 diff --git a/pdf2htmlEX/CMakeLists.txt b/pdf2htmlEX/CMakeLists.txt index 2018ccfa..261b21a3 100644 --- a/pdf2htmlEX/CMakeLists.txt +++ b/pdf2htmlEX/CMakeLists.txt @@ -28,12 +28,15 @@ find_package(PkgConfig) # poppler... we explicitly describe the poppler include and library # paths. # +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../poppler/cmake") include_directories( ../poppler/build/poppler ../poppler/build ../poppler/poppler ../poppler ) +include_directories(${POPPLER_INCLUDE_DIRS}) +link_directories(${POPPLER_LIBRARY_DIRS}) # # The following order is critical as the glib functions use functions # located in the main poppler library @@ -43,6 +46,9 @@ set(POPPLER_LIBRARIES ${POPPLER_LIBRARIES} ${CMAKE_SOURCE_DIR}/../poppler/build/libpoppler.a ) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0>=2.80 gio-2.0>=2.80) +include_directories(${GLIB_INCLUDE_DIRS}) +link_directories(${GLIB_LIBRARY_DIRS}) if(ENABLE_SVG) pkg_check_modules(CAIRO REQUIRED cairo>=1.10.0) @@ -66,6 +72,7 @@ if(ENABLE_SVG) # set(PDF2HTMLEX_LIBS ${PDF2HTMLEX_LIBS} ${FREETYPE_LIBRARIES}) endif() + # SINCE we have a very intimate relationship with a particular version of # fontforge... we explicitly describe the fontforge include and library # paths. @@ -76,7 +83,7 @@ include_directories( ../fontforge/build/inc ../fontforge/inc ) -# +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../fontforge/cmake") include_directories(${FONTFORGE_INCLUDE_DIRS}) link_directories(${FONTFORGE_LIBRARY_DIRS}) set(FONTFORGE_LIBRARIES ${FONTFORGE_LIBRARIES} diff --git a/pdf2htmlEX/src/BackgroundRenderer/BackgroundRenderer.cc b/pdf2htmlEX/src/BackgroundRenderer/BackgroundRenderer.cc index dbd7137e..33b2233b 100644 --- a/pdf2htmlEX/src/BackgroundRenderer/BackgroundRenderer.cc +++ b/pdf2htmlEX/src/BackgroundRenderer/BackgroundRenderer.cc @@ -5,6 +5,7 @@ * Copyright (C) 2013 Lu Wang */ +#include #include #include "HTMLRenderer/HTMLRenderer.h" @@ -55,8 +56,8 @@ void BackgroundRenderer::proof_begin_text_object(GfxState *state, OutputDev * de { PDFRectangle rect(0, 0, state->getPageWidth(), state->getPageHeight()); proof_state.reset(new GfxState(state->getHDPI(), state->getVDPI(), &rect, state->getRotate(), dev->upsideDown())); - proof_state->setFillColorSpace(new GfxDeviceRGBColorSpace()); - proof_state->setStrokeColorSpace(new GfxDeviceRGBColorSpace()); + proof_state->setFillColorSpace(std::make_unique()); + proof_state->setStrokeColorSpace(std::make_unique()); } // Save original render mode in proof_state, and restore in proof_end_text_object() @@ -72,7 +73,7 @@ void BackgroundRenderer::proof_begin_string(GfxState *state, OutputDev * dev) return; double lx = state->getFontSize() / 70, ly = lx; - tm_transform(state->getTextMat(), lx, ly, true); + tm_transform(state->getTextMat().data(), lx, ly, true); proof_state->setLineWidth(sqrt(lx * lx + ly * ly)); static const Color red(1, 0, 0), green(0, 1, 0), blue(0, 0, 1), yellow(1, 1, 0), white(1, 1, 1); diff --git a/pdf2htmlEX/src/BackgroundRenderer/CairoBackgroundRenderer.cc b/pdf2htmlEX/src/BackgroundRenderer/CairoBackgroundRenderer.cc index 4621db9b..e567994c 100644 --- a/pdf2htmlEX/src/BackgroundRenderer/CairoBackgroundRenderer.cc +++ b/pdf2htmlEX/src/BackgroundRenderer/CairoBackgroundRenderer.cc @@ -56,7 +56,7 @@ void CairoBackgroundRenderer::drawChar(GfxState *state, double x, double y, // - OR the text is used as path if((param.fallback || param.proof) || ( (state->getFont()) - && ( (state->getFont()->getWMode()) + && ( (state->getFont()->getWMode() != GfxFont::WritingMode::Horizontal) || ((state->getFont()->getType() == fontType3) && (!param.process_type3)) || (state->getRender() >= 4) ) @@ -85,7 +85,7 @@ void CairoBackgroundRenderer::beginString(GfxState *state, const GooString * str { if (param.proof == 2) proof_begin_string(state, this); - CairoOutputDev::beginString(state, str); + CairoOutputDev::beginString(state, str->toStr()); } void CairoBackgroundRenderer::endTextObject(GfxState *state) diff --git a/pdf2htmlEX/src/BackgroundRenderer/SplashBackgroundRenderer.cc b/pdf2htmlEX/src/BackgroundRenderer/SplashBackgroundRenderer.cc index 780c008a..bd0f4d6e 100644 --- a/pdf2htmlEX/src/BackgroundRenderer/SplashBackgroundRenderer.cc +++ b/pdf2htmlEX/src/BackgroundRenderer/SplashBackgroundRenderer.cc @@ -20,7 +20,7 @@ using std::ifstream; const SplashColor SplashBackgroundRenderer::white = {255,255,255}; SplashBackgroundRenderer::SplashBackgroundRenderer(const string & imgFormat, HTMLRenderer * html_renderer, const Param & param) - : SplashOutputDev(splashModeRGB8, 4, false, (SplashColorPtr)(&white), true, splashThinLineSolid) // DCRH: Make thin line mode = solid + : SplashOutputDev(splashModeRGB8, 4, (SplashColorPtr)(&white), true, splashThinLineSolid) // DCRH: Make thin line mode = solid , html_renderer(html_renderer) , param(param) , format(imgFormat) @@ -75,7 +75,7 @@ void SplashBackgroundRenderer::beginString(GfxState *state, const GooString * st { if (param.proof == 2) proof_begin_string(state, this); - SplashOutputDev::beginString(state, str); + SplashOutputDev::beginString(state, str->toStr()); } void SplashBackgroundRenderer::endTextObject(GfxState *state) @@ -125,8 +125,8 @@ bool SplashBackgroundRenderer::render_page(PDFDoc * doc, int pageno) throw string("Image format not supported: ") + format; SplashError e = bitmap->writeImgFile(splashImageFileFormat, (const char *)fn, param.actual_dpi, param.actual_dpi); - if (e != splashOk) - throw string("Cannot write background image. SplashErrorCode: ") + std::to_string(e); + if (e != SplashError::NoError) + throw string("Cannot write background image. SplashErrorCode: ") + std::to_string((int)e); if(param.embed_image) html_renderer->tmp_files.add((const char *)fn); diff --git a/pdf2htmlEX/src/DrawingTracer.cc b/pdf2htmlEX/src/DrawingTracer.cc index 5d23d421..99c31392 100644 --- a/pdf2htmlEX/src/DrawingTracer.cc +++ b/pdf2htmlEX/src/DrawingTracer.cc @@ -38,7 +38,7 @@ void DrawingTracer::reset(GfxState *state) Matrix ctm, ictm; state->getCTM(&ctm); ctm.invertTo(&ictm); - tm_transform_bbox(ictm.m, pbox); + tm_transform_bbox(ictm.m.data(), pbox); cairo_rectangle_t page_box { pbox[0], pbox[1], pbox[2] - pbox[0], pbox[3] - pbox[1] }; cairo_surface_t * surface = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, &page_box); cairo = cairo_create(surface); @@ -403,7 +403,7 @@ void DrawingTracer::draw_char(GfxState *state, double x, double y, double width, { //printf("x=%f,y=%f,width=%f,height=%f\n", x, y, width, height); Matrix tm, itm; - memcpy(tm.m, state->getTextMat(), sizeof(tm.m)); + memcpy(tm.m.data(), state->getTextMat().data(), sizeof(tm.m)); //printf("tm = %f,%f,%f,%f,%f,%f\n", tm.m[0], tm.m[1], tm.m[2], tm.m[3], tm.m[4], tm.m[5]); double cx = state->getCurX(), cy = state->getCurY(), fs = state->getFontSize(), @@ -424,7 +424,7 @@ void DrawingTracer::draw_char(GfxState *state, double x, double y, double width, //printf("char_m = %f,%f,%f,%f,%f,%f\n", char_m[0], char_m[1], char_m[2], char_m[3], char_m[4], char_m[5]); double final_m[6]; - tm_multiply(final_m, tm.m, char_m); + tm_multiply(final_m, tm.m.data(), char_m); //printf("final_m = %f,%f,%f,%f,%f,%f\n", final_m[0], final_m[1], final_m[2], final_m[3], final_m[4], final_m[5]); double final_after_ctm[6]; diff --git a/pdf2htmlEX/src/HTMLRenderer/font.cc b/pdf2htmlEX/src/HTMLRenderer/font.cc index ff27da24..7502c46a 100644 --- a/pdf2htmlEX/src/HTMLRenderer/font.cc +++ b/pdf2htmlEX/src/HTMLRenderer/font.cc @@ -158,7 +158,7 @@ string HTMLRenderer::dump_embedded_font (GfxFont * font, FontInfo & info) throw 0; } - obj.streamReset(); + obj.streamRewind(); filepath = (char*)str_fmt("%s/f%llx%s", param.tmp_dir.c_str(), fn_id, suffix.c_str()); tmp_files.add(filepath); @@ -205,8 +205,8 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) auto used_map = preprocessor.get_code_map(hash_ref(font->getID())); //calculate transformed metrics - const double * font_bbox = font->getFontBBox(); - const double * font_matrix = font->getFontMatrix(); + const double * font_bbox = font->getFontBBox().data(); + const double * font_matrix = font->getFontMatrix().data(); double transformed_bbox[4]; memcpy(transformed_bbox, font_bbox, 4 * sizeof(double)); /* @@ -265,12 +265,13 @@ string HTMLRenderer::dump_type3_font (GfxFont * font, FontInfo & info) cairo_matrix_multiply(&m1, &m1, &m2); cairo_set_font_matrix(cr, &m1); - cairo_glyph_t glyph; - glyph.index = cur_font->getGlyph(code, nullptr, 0); - glyph.x = 0; - glyph.y = GLYPH_DUMP_EM_SIZE; - cairo_show_glyphs(cr, &glyph, 1); - + if (auto glyphIndexOpt = cur_font->getGlyph(code)) { + cairo_glyph_t glyph; + glyph.index = *glyphIndexOpt; + glyph.x = 0; + glyph.y = GLYPH_DUMP_EM_SIZE; + cairo_show_glyphs(cr, &glyph, 1); + } // apply the type 3 font's font matrix before m1 // such that we got the mapping from type 3 font space to user space, then we will be able to calculate mapped position for ox,oy and glyph_width @@ -403,8 +404,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo ofstream((char*)fn, ofstream::binary) << ifstream(filepath).rdbuf(); } - int * code2GID = nullptr; - int code2GID_len = 0; + std::vector code2GID; int maxcode = 0; Gfx8BitFont * font_8bit = nullptr; @@ -486,10 +486,9 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo else { ffw_reencode_glyph_order(); - if(std::unique_ptr fftt = FoFiTrueType::load((char*)filepath.c_str())) + if(std::unique_ptr fftt = FoFiTrueType::load(filepath.c_str(), 0)) { code2GID = font_8bit->getCodeToGIDMap(fftt.get()); - code2GID_len = 256; } } } @@ -544,17 +543,16 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo // To locate CID2GID for the font // as in CairoFontEngine.cc - if((code2GID = _font->getCIDToGID())) + if(!(code2GID = _font->getCIDToGID()).empty()) { // use the mapping stored in _font - code2GID_len = _font->getCIDToGIDLen(); } else { // use the mapping stored in the file - if(std::unique_ptr fftt = FoFiTrueType::load((char*)filepath.c_str())) + if(std::unique_ptr fftt = FoFiTrueType::load(filepath.c_str(), 0)) { - code2GID = _font->getCodeToGIDMap(fftt.get(), &code2GID_len); + code2GID = _font->getCodeToGIDMap(fftt.get()); } } } @@ -592,17 +590,13 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo unordered_set codeset; bool name_conflict_warned = false; - auto ctu = font->getToUnicode(); - // NOTE: Poppler has changed its effective ABI - // in now expects the USER to increment any ref counters - assert(ctu); - ((CharCodeToUnicode *)ctu)->incRefCnt(); + const CharCodeToUnicode* ctu = font->getToUnicode(); std::fill(cur_mapping.begin(), cur_mapping.end(), -1); std::fill(width_list.begin(), width_list.end(), -1); - if(code2GID) - maxcode = min(maxcode, code2GID_len - 1); + if(!code2GID.empty()) + maxcode = min(maxcode, code2GID.size() - 1); bool is_truetype = is_truetype_suffix(suffix); int max_key = maxcode; @@ -625,7 +619,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo } int mapped_code = cur_code; - if(code2GID) + if(!code2GID.empty()) { // for fonts with GID (e.g. TTF) we need to map GIDs instead of codes if((mapped_code = code2GID[cur_code]) == 0) continue; @@ -639,7 +633,7 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo if(info.use_tounicode) { int n = ctu ? - (((CharCodeToUnicode *)ctu)->mapToUnicode(cur_code, &pu)) : + ctu->mapToUnicode(cur_code, &pu) : 0; u = check_unicode(pu, n, cur_code, font); } @@ -760,9 +754,6 @@ void HTMLRenderer::embed_font(const string & filepath, GfxFont * font, FontInfo { cerr << "space width: " << info.space_width << endl; } - - if(ctu) - ((CharCodeToUnicode *)ctu)->decRefCnt(); } /* @@ -897,7 +888,7 @@ const FontInfo * HTMLRenderer::install_font(GfxFont * font) #endif return &new_font_info; } - if(font->getWMode()) { + if(font->getWMode() != GfxFont::WritingMode::Horizontal) { cerr << "Writing mode is unsupported and will be rendered as Image" << endl; export_remote_default_font(new_fn_id); return &new_font_info; diff --git a/pdf2htmlEX/src/HTMLRenderer/link.cc b/pdf2htmlEX/src/HTMLRenderer/link.cc index c7fcd959..7bc92d85 100644 --- a/pdf2htmlEX/src/HTMLRenderer/link.cc +++ b/pdf2htmlEX/src/HTMLRenderer/link.cc @@ -273,7 +273,7 @@ void HTMLRenderer::processLink(AnnotLink * al) double r,g,b; if(color && (color->getSpace() == AnnotColor::colorRGB)) { - const double * v = color->getValues(); + const auto v = color->getValues(); r = v[0]; g = v[1]; b = v[2]; diff --git a/pdf2htmlEX/src/HTMLRenderer/state.cc b/pdf2htmlEX/src/HTMLRenderer/state.cc index 4595c63d..128525b4 100644 --- a/pdf2htmlEX/src/HTMLRenderer/state.cc +++ b/pdf2htmlEX/src/HTMLRenderer/state.cc @@ -252,7 +252,7 @@ void HTMLRenderer::check_state_change(GfxState * state) m1[5] = state->getRise(); m1[1] = m1[2] = m1[4] = 0; - tm_multiply(m2, state->getCTM(), state->getTextMat()); + tm_multiply(m2, state->getCTM().data(), state->getTextMat().data()); tm_multiply(new_text_tm, m2, m1); if(!tm_equal(new_text_tm, cur_text_tm)) diff --git a/pdf2htmlEX/src/HTMLRenderer/text.cc b/pdf2htmlEX/src/HTMLRenderer/text.cc index 723704ee..01bd032d 100644 --- a/pdf2htmlEX/src/HTMLRenderer/text.cc +++ b/pdf2htmlEX/src/HTMLRenderer/text.cc @@ -25,7 +25,7 @@ using std::endl; void HTMLRenderer::drawString(GfxState * state, const GooString * s) { - if(s->getLength() == 0) + if(s->empty()) return; auto font = state->getFont(); @@ -41,7 +41,7 @@ void HTMLRenderer::drawString(GfxState * state, const GooString * s) if(state->getFont() - && ( (state->getFont()->getWMode()) + && ( (state->getFont()->getWMode() != GfxFont::WritingMode::Horizontal) || ((state->getFont()->getType() == fontType3) && (!param.process_type3)) || (state->getRender() >= 4) ) @@ -58,8 +58,8 @@ void HTMLRenderer::drawString(GfxState * state, const GooString * s) // Now ready to output // get the unicodes - const char *p = (s->toStr()).c_str(); - int len = s->getLength(); + const char *p = s->c_str(); + int len = s->size(); //accumulated displacement of chars in this string, in text object space double dx = 0; diff --git a/pdf2htmlEX/src/StateManager.h b/pdf2htmlEX/src/StateManager.h index 9b6d44ea..169b8337 100644 --- a/pdf2htmlEX/src/StateManager.h +++ b/pdf2htmlEX/src/StateManager.h @@ -107,9 +107,9 @@ class StateManager // return id long long install(const double * new_value) { Matrix m; - memcpy(m.m, new_value, 4 * sizeof(double)); + memcpy(m.m.data(), new_value, 4 * sizeof(double)); auto iter = value_map.lower_bound(m); - if((iter != value_map.end()) && (tm_equal(m.m, iter->first.m, 4))) + if((iter != value_map.end()) && (tm_equal(m.m.data(), iter->first.m.data(), 4))) { return iter->second; } @@ -316,7 +316,7 @@ class TransformMatrixManager : public StateManager