diff --git a/YACReader/YACReader.pri b/YACReader/YACReader.pri index ff28a0d9..f4c3788d 100644 --- a/YACReader/YACReader.pri +++ b/YACReader/YACReader.pri @@ -37,14 +37,20 @@ LIBS += -lGLU macx{ #INCLUDEPATH += "/Volumes/Mac OS X Lion/usr/X11/include" -isEqual(QT_MAJOR_VERSION, 5) { -INCLUDEPATH += /usr/local/include/poppler/qt5 -LIBS += -L/usr/local/lib -lpoppler-qt5 -} -else { -INCLUDEPATH += /usr/local/include/poppler/qt4 -LIBS += -L/usr/local/lib -lpoppler-qt4 -} +#isEqual(QT_MAJOR_VERSION, 5) { +#INCLUDEPATH += /usr/local/include/poppler/qt5 +#LIBS += -L/usr/local/lib -lpoppler-qt5 +#} +#else { +#INCLUDEPATH += /usr/local/include/poppler/qt4 +#LIBS += -L/usr/local/lib -lpoppler-qt4 +#} + +LIBS += -framework Foundation -framework ApplicationServices + +OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm +HEADERS += $$PWD/../common/pdf_comic.h +CONFIG += objective_c } QT += network opengl diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 596894be..342e72b1 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -48,15 +48,22 @@ LIBS += -lGLU macx{ #INCLUDEPATH += "/Volumes/Mac OS X Lion/usr/X11/include" -isEqual(QT_MAJOR_VERSION, 5) { -INCLUDEPATH += /usr/local/include/poppler/qt5 -LIBS += -L/usr/local/lib -lpoppler-qt5 -} -else { -INCLUDEPATH += /usr/local/include/poppler/qt4 -LIBS += -L/usr/local/lib -lpoppler-qt4 -} -QT += macextras +#isEqual(QT_MAJOR_VERSION, 5) { +#INCLUDEPATH += /usr/local/include/poppler/qt5 +#LIBS += -L/usr/local/lib -lpoppler-qt5 +#} +#else { +#INCLUDEPATH += /usr/local/include/poppler/qt4 +#LIBS += -L/usr/local/lib -lpoppler-qt4 +#} +#QT += macextras + +LIBS += -framework Foundation -framework ApplicationServices + +OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm +HEADERS += $$PWD/../common/pdf_comic.h +CONFIG += objective_c + } #CONFIG += release diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index da7c490c..f480dcc4 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -22,12 +22,18 @@ #include using namespace std; +#ifdef Q_OS_MAC + #include "pdf_comic.h" +#else + #if QT_VERSION >= 0x050000 #include "poppler-qt5.h" #else #include "poppler-qt4.h" #endif +#endif + //-------------------------------------------------------------------------------- LibraryCreator::LibraryCreator() :creation(false) @@ -500,11 +506,24 @@ void ThumbnailCreator::create() if(fi.suffix().compare("pdf",Qt::CaseInsensitive) == 0) { + +#ifdef Q_OS_MAC + MacOSXPDFComic * pdfComic = new MacOSXPDFComic(); + if(!pdfComic->openComic(_fileSource)) + { + delete pdfComic; + QImage p; + p.load(":/images/notCover.png"); + p.save(_target); + return; + } +#else Poppler::Document * pdfComic = Poppler::Document::load(_fileSource); - if (!pdfComic) +#endif + if (!pdfComic) { QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; - delete pdfComic; + //delete pdfComic; //TODO check if the delete is needed pdfComic = 0; QImage p; p.load(":/images/notCover.png"); @@ -514,8 +533,12 @@ void ThumbnailCreator::create() _numPages = pdfComic->numPages(); if(_numPages >= _coverPage) { - - QImage p = pdfComic->page(_coverPage-1)->renderToImage(72,72); //TODO check if the page is valid +#ifdef Q_OS_MAC + { + QImage p = pdfComic->getPage(_coverPage-1); //TODO check if the page is valid +#else + QImage p = pdfComic->page(_coverPage-1)->renderToImage(72,72); +#endif _cover = QPixmap::fromImage(p); if(_target!="") { @@ -526,6 +549,10 @@ void ThumbnailCreator::create() scaled = p.scaledToWidth(480,Qt::SmoothTransformation); scaled.save(_target,0,75); } +#ifdef Q_OS_MAC + } + pdfComic->releaseLastPageData(); +#endif } else if(_target!="") { @@ -534,6 +561,8 @@ void ThumbnailCreator::create() p.load(":/images/notCover.png"); p.save(_target); } + + delete pdfComic; } else { diff --git a/common/comic.cpp b/common/comic.cpp index 880edd32..6c5b4821 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -633,18 +633,32 @@ bool PDFComic::load(const QString & path, const ComicDB & comic) void PDFComic::process() { +#ifdef Q_OS_MAC + pdfComic = new MacOSXPDFComic(); + if(!pdfComic->openComic(_path)) + { + delete pdfComic; + emit errorOpening(); + return; + } +#else + + pdfComic = Poppler::Document::load(_path); if (!pdfComic) { - delete pdfComic; - pdfComic = 0; + //delete pdfComic; + //pdfComic = 0; emit errorOpening(); return; } + //pdfComic->setRenderHint(Poppler::Document::Antialiasing, true); pdfComic->setRenderHint(Poppler::Document::TextAntialiasing, true); +#endif + int nPages = pdfComic->numPages(); emit pageChanged(0); // this indicates new comic, index=0 emit numPages(nPages); @@ -672,6 +686,21 @@ void PDFComic::process() void PDFComic::renderPage(int page) { +#ifdef Q_OS_MAC + { + QImage img = pdfComic->getPage(page); + if(!img.isNull()) + { + QByteArray ba; + QBuffer buf(&ba); + img.save(&buf, "jpg"); + _pages[page] = ba; + emit imageLoaded(page); + emit imageLoaded(page,_pages[page]); + } + } + pdfComic->releaseLastPageData(); +#else Poppler::Page* pdfpage = pdfComic->page(page); if (pdfpage) { @@ -684,6 +713,7 @@ void PDFComic::renderPage(int page) emit imageLoaded(page); emit imageLoaded(page,_pages[page]); } +#endif } Comic * FactoryComic::newComic(const QString & path) diff --git a/common/comic.h b/common/comic.h index 1ebd8ed2..d034c470 100644 --- a/common/comic.h +++ b/common/comic.h @@ -10,12 +10,20 @@ #include "bookmarks.h" +#ifdef Q_OS_MAC + +#include "pdf_comic.h" + +#else + #if QT_VERSION >= 0x050000 #include "poppler-qt5.h" #else #include "poppler-qt4.h" #endif +#endif + class ComicDB; //#define EXTENSIONS << "*.jpg" << "*.jpeg" << "*.png" << "*.gif" << "*.tiff" << "*.tif" << "*.bmp" Comic::getSupportedImageFormats() //#define EXTENSIONS_LITERAL << ".jpg" << ".jpeg" << ".png" << ".gif" << ".tiff" << ".tif" << ".bmp" //Comic::getSupportedImageLiteralFormats() @@ -138,7 +146,11 @@ class ComicDB; Q_OBJECT private: //pdf +#ifdef Q_OS_MAC + MacOSXPDFComic * pdfComic; +#else Poppler::Document * pdfComic; +#endif void renderPage(int page); //void run(); diff --git a/common/pdf_comic.h b/common/pdf_comic.h new file mode 100644 index 00000000..7c5d7f48 --- /dev/null +++ b/common/pdf_comic.h @@ -0,0 +1,22 @@ +#ifndef PDF_COMIC_H +#define PDF_COMIC_H + +#include +#include + +class MacOSXPDFComic +{ +public: + MacOSXPDFComic(); + ~MacOSXPDFComic(); + bool openComic(const QString & path); + void closeComic(); + unsigned int numPages(); + QImage getPage(const int page); + void releaseLastPageData(); +private: + void * document; + void * lastPageData; +}; + +#endif // PDF_COMIC_H diff --git a/common/pdf_comic.mm b/common/pdf_comic.mm new file mode 100644 index 00000000..7f9b32ce --- /dev/null +++ b/common/pdf_comic.mm @@ -0,0 +1,117 @@ +#include "pdf_comic.h" + +#import +#import +#import + +#include "QsLog.h" +#include "QsLogDest.h" + + +MacOSXPDFComic::MacOSXPDFComic() +{ + +} + +MacOSXPDFComic::~MacOSXPDFComic() +{ + CGPDFDocumentRelease((CGPDFDocumentRef)document); +} + +bool MacOSXPDFComic::openComic(const QString &path) +{ + + CFURLRef pdfFileUrl; + CFStringRef str; + str=CFStringCreateWithCString( kCFAllocatorDefault,path.toUtf8().data(),kCFStringEncodingUTF8); + pdfFileUrl=CFURLCreateWithFileSystemPath( kCFAllocatorDefault,str,kCFURLPOSIXPathStyle,true ); + + CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfFileUrl); + + document = pdf; + + CFRelease(str); + CFRelease(pdfFileUrl); + + return true; +} + +void MacOSXPDFComic::closeComic() +{ + //CGPDFDocumentRelease((CGPDFDocumentRef)document); +} + +unsigned int MacOSXPDFComic::numPages() +{ + return (int)CGPDFDocumentGetNumberOfPages((CGPDFDocumentRef)document); +} + +QImage MacOSXPDFComic::getPage(const int pageNum) +{ + CGPDFPageRef page = CGPDFDocumentGetPage((CGPDFDocumentRef)document, pageNum+1); + // Changed this line for the line above which is a generic line + //CGPDFPageRef page = [self getPage:page_number]; + + + + CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); + int width = 1200; + + //NSLog(@"-----%f",pageRect.size.width); + CGFloat pdfScale = float(width)/pageRect.size.width; + + pageRect.size = CGSizeMake(pageRect.size.width*pdfScale, pageRect.size.height*pdfScale); + pageRect.origin = CGPointZero; + + CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef bitmapContext = CGBitmapContextCreate(NULL, + pageRect.size.width, + pageRect.size.height, + 8, 0, + genericColorSpace, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little + ); + + CGContextSetInterpolationQuality(bitmapContext, kCGInterpolationHigh); + CGContextSetRenderingIntent(bitmapContext, kCGRenderingIntentDefault); + CGContextSetRGBFillColor( bitmapContext, 1.0, 1.0, 1.0, 1.0 ); + CGContextFillRect( bitmapContext, CGContextGetClipBoundingBox( bitmapContext )); + + //CGContextTranslateCTM( bitmapContext, 0, pageRect.size.height ); + //CGContextScaleCTM( bitmapContext, 1.0, -1.0 ); + + CGContextConcatCTM(bitmapContext, CGAffineTransformMakeScale(pdfScale, pdfScale)); + + + /*CGAffineTransform pdfXfm = CGPDFPageGetDrawingTransform( page, kCGPDFMediaBox, CGRectMake(pageRect.origin.x, pageRect.origin.y, pageRect.size.width, pageRect.size.height) , 0, true ); + */ + //CGContextConcatCTM( bitmapContext, pdfXfm ); + + CGContextDrawPDFPage(bitmapContext, page); + + CGImageRef image = CGBitmapContextCreateImage(bitmapContext); + + QImage qtImage; + + CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider(image)); + + lastPageData = (void *)dataRef; + + const uchar *bytes = (const uchar *)CFDataGetBytePtr(dataRef); + + qtImage = QImage(bytes, pageRect.size.width, pageRect.size.height, QImage::Format_ARGB32); + + CGImageRelease(image); + //CFRelease(dataRef); + CGContextRelease(bitmapContext); + //CGPDFPageRelease(page); + CGColorSpaceRelease(genericColorSpace); + + return qtImage; +} + +void MacOSXPDFComic::releaseLastPageData() +{ + CFRelease((CFDataRef)lastPageData); +} + diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 11a49487..49132fb2 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -8,7 +8,7 @@ #endif -#define VERSION "7.0.1" +#define VERSION "7.0.2" #define PATH "PATH" #define MAG_GLASS_SIZE "MAG_GLASS_SIZE" diff --git a/compressed_archive/README_7zip.txt b/compressed_archive/README_7zip.txt new file mode 100644 index 00000000..003e3f39 --- /dev/null +++ b/compressed_archive/README_7zip.txt @@ -0,0 +1,5 @@ +If you are trying to compile YACReader, you need to donwload de source code of 7zip (Windows) or p7zip (Linux/MacOSX). + +Please, extract it and rename the folder to lib7zip (Windows) or libp7zip (Linux/MacOSX), then copy it to $YACREADER_SRC/compressed_archive/ (this folder) + +YACReader is compiled using 7zip/p7zip 9.20. \ No newline at end of file diff --git a/create-dmg b/create-dmg new file mode 100755 index 00000000..b581913f --- /dev/null +++ b/create-dmg @@ -0,0 +1,221 @@ +#! /bin/bash + +# Create a read-only disk image of the contents of a folder + +set -e; + +function pure_version() { + echo '1.0.0.2' +} + +function version() { + echo "create-dmg $(pure_version)" +} + +function usage() { + version + echo "Creates a fancy DMG file." + echo "Usage: $(basename $0) options... image.dmg source_folder" + echo "All contents of source_folder will be copied into the disk image." + echo "Options:" + echo " --volname name" + echo " set volume name (displayed in the Finder sidebar and window title)" + echo " --volicon icon.icns" + echo " set volume icon" + echo " --background pic.png" + echo " set folder background image (provide png, gif, jpg)" + echo " --window-pos x y" + echo " set position the folder window" + echo " --window-size width height" + echo " set size of the folder window" + echo " --icon-size icon_size" + echo " set window icons size (up to 128)" + echo " --icon file_name x y" + echo " set position of the file's icon" + echo " --hide-extension file_name" + echo " hide the extension of file" + echo " --custom-icon file_name custom_icon_or_sample_file x y" + echo " set position and custom icon" + echo " --app-drop-link x y" + echo " make a drop link to Applications, at location x,y" + echo " --eula eula_file" + echo " attach a license file to the dmg" + echo " --no-internet-enable" + echo " disable automatic mount©" + echo " --version show tool version number" + echo " -h, --help display this help" + exit 0 +} + +WINX=10 +WINY=60 +WINW=500 +WINH=350 +ICON_SIZE=128 + +while test "${1:0:1}" = "-"; do + case $1 in + --volname) + VOLUME_NAME="$2" + shift; shift;; + --volicon) + VOLUME_ICON_FILE="$2" + shift; shift;; + --background) + BACKGROUND_FILE="$2" + BACKGROUND_FILE_NAME="$(basename $BACKGROUND_FILE)" + BACKGROUND_CLAUSE="set background picture of opts to file \".background:$BACKGROUND_FILE_NAME\"" + shift; shift;; + --icon-size) + ICON_SIZE="$2" + shift; shift;; + --window-pos) + WINX=$2; WINY=$3 + shift; shift; shift;; + --window-size) + WINW=$2; WINH=$3 + shift; shift; shift;; + --icon) + POSITION_CLAUSE="${POSITION_CLAUSE}set position of item \"$2\" to {$3, $4} +" + shift; shift; shift; shift;; + --hide-extension) + HIDING_CLAUSE="${HIDING_CLAUSE}set the extension hidden of item \"$2\" to true" + shift; shift;; + --custom-icon) + shift; shift; shift; shift; shift;; + -h | --help) + usage;; + --version) + version; exit 0;; + --pure-version) + pure_version; exit 0;; + --app-drop-link) + APPLICATION_LINK=$2 + APPLICATION_CLAUSE="set position of item \"Applications\" to {$2, $3} +" + shift; shift; shift;; + --eula) + EULA_RSRC=$2 + shift; shift;; + --no-internet-enable) + NOINTERNET=1 + shift;; + -*) + echo "Unknown option $1. Run with --help for help." + exit 1;; + esac +done + +test -z "$2" && { + echo "Not enough arguments. Invoke with --help for help." + exit 1 +} + +DMG_PATH="$1" +DMG_DIRNAME="$(dirname "$DMG_PATH")" +DMG_DIR="$(cd $DMG_DIRNAME > /dev/null; pwd)" +DMG_NAME="$(basename "$DMG_PATH")" +DMG_TEMP_NAME="$DMG_DIR/rw.${DMG_NAME}" +SRC_FOLDER="$(cd "$2" > /dev/null; pwd)" +test -z "$VOLUME_NAME" && VOLUME_NAME="$(basename "$DMG_PATH" .dmg)" + +AUX_PATH="$(dirname $0)/support" + +test -d "$AUX_PATH" || { + echo "Cannot find support directory: $AUX_PATH" + exit 1 +} + +if [ -f "$SRC_FOLDER/.DS_Store" ]; then + echo "Deleting any .DS_Store in source folder" + rm "$SRC_FOLDER/.DS_Store" +fi + +# Create the image +echo "Creating disk image..." +test -f "${DMG_TEMP_NAME}" && rm -f "${DMG_TEMP_NAME}" +ACTUAL_SIZE=`du -sm "$SRC_FOLDER" | sed -e 's/ .*//g'` +DISK_IMAGE_SIZE=$(expr $ACTUAL_SIZE + 20) +hdiutil create -srcfolder "$SRC_FOLDER" -volname "${VOLUME_NAME}" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${DISK_IMAGE_SIZE}m "${DMG_TEMP_NAME}" + +# mount it +echo "Mounting disk image..." +MOUNT_DIR="/Volumes/${VOLUME_NAME}" + +# try unmount dmg if it was mounted previously (e.g. developer mounted dmg, installed app and forgot to unmount it) +echo "Unmounting disk image..." +DEV_NAME=$(hdiutil info | egrep '^/dev/' | sed 1q | awk '{print $1}') +test -d "${MOUNT_DIR}" && hdiutil detach "${DEV_NAME}" + +echo "Mount directory: $MOUNT_DIR" +DEV_NAME=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_TEMP_NAME}" | egrep '^/dev/' | sed 1q | awk '{print $1}') +echo "Device name: $DEV_NAME" + +if ! test -z "$BACKGROUND_FILE"; then + echo "Copying background file..." + test -d "$MOUNT_DIR/.background" || mkdir "$MOUNT_DIR/.background" + cp "$BACKGROUND_FILE" "$MOUNT_DIR/.background/$BACKGROUND_FILE_NAME" +fi + +if ! test -z "$APPLICATION_LINK"; then + echo "making link to Applications dir" + echo $MOUNT_DIR + ln -s /Applications "$MOUNT_DIR/Applications" +fi + +if ! test -z "$VOLUME_ICON_FILE"; then + echo "Copying volume icon file '$VOLUME_ICON_FILE'..." + cp "$VOLUME_ICON_FILE" "$MOUNT_DIR/.VolumeIcon.icns" + SetFile -c icnC "$MOUNT_DIR/.VolumeIcon.icns" +fi + +# run applescript +APPLESCRIPT=$(mktemp -t createdmg) +cat "$AUX_PATH/template.applescript" | sed -e "s/WINX/$WINX/g" -e "s/WINY/$WINY/g" -e "s/WINW/$WINW/g" -e "s/WINH/$WINH/g" -e "s/BACKGROUND_CLAUSE/$BACKGROUND_CLAUSE/g" -e "s/ICON_SIZE/$ICON_SIZE/g" | perl -pe "s/POSITION_CLAUSE/$POSITION_CLAUSE/g" | perl -pe "s/APPLICATION_CLAUSE/$APPLICATION_CLAUSE/g" | perl -pe "s/HIDING_CLAUSE/$HIDING_CLAUSE/" >"$APPLESCRIPT" + +echo "Running Applescript: /usr/bin/osascript \"${APPLESCRIPT}\" \"${VOLUME_NAME}\"" +"/usr/bin/osascript" "${APPLESCRIPT}" "${VOLUME_NAME}" || true +echo "Done running the applescript..." +sleep 4 + +rm "$APPLESCRIPT" + +# make sure it's not world writeable +echo "Fixing permissions..." +chmod -Rf go-w "${MOUNT_DIR}" &> /dev/null || true +echo "Done fixing permissions." + +# make the top window open itself on mount: +echo "Blessing started" +bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}" +echo "Blessing finished" + +if ! test -z "$VOLUME_ICON_FILE"; then + # tell the volume that it has a special file attribute + SetFile -a C "$MOUNT_DIR" +fi + +# unmount +echo "Unmounting disk image..." +hdiutil detach "${DEV_NAME}" + +# compress image +echo "Compressing disk image..." +hdiutil convert "${DMG_TEMP_NAME}" -format UDZO -imagekey zlib-level=9 -o "${DMG_DIR}/${DMG_NAME}" +rm -f "${DMG_TEMP_NAME}" + +# adding EULA resources +if [ ! -z "${EULA_RSRC}" -a "${EULA_RSRC}" != "-null-" ]; then + echo "adding EULA resources" + "${AUX_PATH}/dmg-license.py" "${DMG_DIR}/${DMG_NAME}" "${EULA_RSRC}" +fi + +if [ ! -z "${NOINTERNET}" -a "${NOINTERNET}" == 1 ]; then + echo "not setting 'internet-enable' on the dmg" +else + hdiutil internet-enable -yes "${DMG_DIR}/${DMG_NAME}" +fi + +echo "Disk image done" +exit 0