From 673d0c6fd26c953013ce54ed753f8f0dea42fc82 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 1 Oct 2009 13:24:27 -0600 Subject: [PATCH] Windows: Rebuild the complete calibre stack using only Microsoft tools. This should (hopefully) fix various (especially PDF related) crashes. --- setup/build_environment.py | 48 +++--- setup/extensions.py | 25 ++- setup/installer/windows/calibre/calibre.mpi | 18 ++- setup/installer/windows/freeze.py | 42 ++--- setup/installer/windows/notes.rst | 167 +++++++++++++++++++ src/calibre/ebooks/pdf/main.cpp | 3 +- src/calibre/ebooks/pdf/reflow.cpp | 2 +- src/calibre/translations/zh_CN.po | 4 +- src/calibre/utils/fonts/Makefile.msvc | 2 + src/calibre/utils/fonts/__init__.py | 9 +- src/calibre/utils/fonts/winfonts.cpp | 168 ++++++++++++++++++++ 11 files changed, 410 insertions(+), 78 deletions(-) create mode 100644 setup/installer/windows/notes.rst create mode 100644 src/calibre/utils/fonts/Makefile.msvc create mode 100644 src/calibre/utils/fonts/winfonts.cpp diff --git a/setup/build_environment.py b/setup/build_environment.py index f5bc969581..1eab15b630 100644 --- a/setup/build_environment.py +++ b/setup/build_environment.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, socket, struct, subprocess, glob +import os, socket, struct, subprocess from distutils.spawn import find_executable from PyQt4 import pyqtconfig @@ -91,33 +91,31 @@ podofo_inc = '/usr/include/podofo' podofo_lib = '/usr/lib' if iswindows: - fc_inc = r'C:\cygwin\home\kovid\fontconfig\include\fontconfig' - fc_lib = r'C:\cygwin\home\kovid\fontconfig\lib' - poppler_inc_dirs = consolidate('POPPLER_INC_DIR', - (r'C:\cygwin\home\kovid\poppler\poppler-source\poppler;' - r'C:\cygwin\home\kovid\poppler\poppler-source;' - r'C:\cygwin\home\kovid\poppler\poppler-build;' - r'C:\cygwin\home\kovid\poppler\poppler-build\poppler')) - popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[1]+r'\qt4'] - poppler_lib_dirs = consolidate('POPPLER_LIB_DIR', - (r'C:\cygwin\home\kovid\poppler\poppler-build\qt4\src\Release;' - r'C:\cygwin\home\kovid\poppler\poppler-build\Release')) - popplerqt4_lib_dirs = poppler_lib_dirs - poppler_libs = [] - poppler_objs = glob.glob(r'C:\cygwin\home\kovid\poppler\poppler-build\poppler.dir\Release\*.obj') - popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4'] - png_inc_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\include'] - png_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib'] - png_libs = [r'libpng'] - jpg_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib'] + prefix = r'C:\cygwin\home\kovid\sw' + sw_inc_dir = os.path.join(prefix, 'include') + sw_lib_dir = os.path.join(prefix, 'lib') + fc_inc = os.path.join(sw_inc_dir, 'fontconfig') + fc_lib = sw_lib_dir + png_inc_dirs = [sw_inc_dir] + png_lib_dirs = [sw_lib_dir] + png_libs = ['png12'] + jpg_lib_dirs = [sw_lib_dir] jpg_libs = ['jpeg'] + ft_lib_dirs = [sw_lib_dir] + ft_libs = ['freetype'] + poppler_inc_dirs = consolidate('POPPLER_INC_DIR', + r'%s\poppler;%s'%(sw_inc_dir, sw_inc_dir)) + + popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[1]+r'\qt4'] + poppler_lib_dirs = consolidate('POPPLER_LIB_DIR', sw_lib_dir) + popplerqt4_lib_dirs = poppler_lib_dirs + poppler_libs = ['poppler'] + popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4'] magick_inc_dirs = [r'C:\cygwin\home\kovid\ImageMagick-6.5.6-Q16\include'] magick_lib_dirs = [r'C:\cygwin\home\kovid\ImageMagick-6.5.6-Q16\lib'] magick_libs = ['CORE_RL_wand_', 'CORE_RL_magick_'] - ft_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib'] - ft_libs = ['freetype'] - podofo_inc = 'C:\\podofo\\include\\podofo' - podofo_lib = r'C:\podofo' + podofo_inc = os.path.join(sw_inc_dir, 'podofo') + podofo_lib = sw_lib_dir elif isosx: fc_inc = '/Users/kovid/fontconfig/include/fontconfig' fc_lib = '/Users/kovid/fontconfig/lib' @@ -137,7 +135,7 @@ elif isosx: magick_libs = ['MagickWand', 'MagickCore'] png_inc_dirs = consolidate('PNG_INC_DIR', '/usr/local/include') png_lib_dirs = consolidate('PNG_LIB_DIR', '/usr/local/lib') - png_libs = ['png'] + png_libs = ['png12'] else: # Include directories poppler_inc_dirs = pkgconfig_include_dirs('poppler', diff --git a/setup/extensions.py b/setup/extensions.py index 7228cf3d03..17d82f3ff9 100644 --- a/setup/extensions.py +++ b/setup/extensions.py @@ -16,7 +16,7 @@ from setup.build_environment import fc_inc, fc_lib, \ fc_error, poppler_libs, poppler_lib_dirs, poppler_inc_dirs, podofo_inc, \ podofo_lib, podofo_error, poppler_error, pyqt, OSX_SDK, NMAKE, \ leopard_build, QMAKE, msvc, MT, win_inc, win_lib, png_inc_dirs, \ - magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, poppler_objs, \ + magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, \ magick_error, magick_libs, ft_lib_dirs, ft_libs, jpg_libs, jpg_lib_dirs MT isunix = islinux or isosx @@ -26,8 +26,8 @@ make = 'make' if isunix else NMAKE class Extension(object): def absolutize(self, paths): - return [x if os.path.isabs(x) else os.path.join(SRC, x.replace('/', - os.sep)) for x in paths] + return list(set([x if os.path.isabs(x) else os.path.join(SRC, x.replace('/', + os.sep)) for x in paths])) def __init__(self, name, sources, **kwargs): @@ -61,7 +61,6 @@ extensions = [ libraries=poppler_libs+magick_libs+png_libs+ft_libs+jpg_libs+pdfreflow_libs, lib_dirs=poppler_lib_dirs+magick_lib_dirs+png_lib_dirs+ft_lib_dirs+jpg_lib_dirs, inc_dirs=poppler_inc_dirs+magick_inc_dirs+png_inc_dirs, - extra_objs=poppler_objs, error=reflow_error, cflags=['-DPNG_SKIP_SETJMP_CHECK'] if islinux else [] ), @@ -161,7 +160,7 @@ if isosx: if iswindows: cc = cxx = msvc.cc cflags = '/c /nologo /Ox /MD /W3 /EHsc /DNDEBUG'.split() - ldflags = '/DLL /nologo /INCREMENTAL:NO'.split() + ldflags = '/DLL /nologo /INCREMENTAL:NO /NODEFAULTLIB:libcmt.lib'.split() #cflags = '/c /nologo /Ox /MD /W3 /EHsc /Zi'.split() #ldflags = '/DLL /nologo /INCREMENTAL:NO /DEBUG'.split() @@ -372,6 +371,8 @@ class BuildPDF2XML(Command): def run(self, opts): dest = os.path.expanduser('~/bin/pdf2xml') + if iswindows: + dest = r'C:\cygwin\home\kovid\sw\bin\pdf2xml.exe' odest = self.j(self.d(self.SRC), 'build', 'objects', 'pdf2xml') if not os.path.exists(odest): os.makedirs(odest) @@ -380,11 +381,15 @@ class BuildPDF2XML(Command): for src in reflow_sources: if src.endswith('python.cpp'): continue - obj = self.j(odest, self.b(src+'.o')) + obj = self.j(odest, self.b(src+('.obj' if iswindows else '.o'))) if self.newer(obj, [src]+reflow_headers): - cmd = ['g++', '-pthread', '-pedantic', '-ggdb', '-c', '-Wall', '-I/usr/include/poppler', + cmd = [cxx, '-pthread', '-pedantic', '-ggdb', '-c', '-Wall', '-I/usr/include/poppler', '-I/usr/include/ImageMagick', '-DPDF2XML', '-o', obj, src] + if iswindows: + cmd = [cxx, '/c', '/MD', '/W3', '/EHsc', '/Zi', '/DPDF2XML'] + cmd += ['-I'+x for x in poppler_inc_dirs+magick_inc_dirs] + cmd += ['/Fo'+obj, src] self.info(*cmd) subprocess.check_call(cmd) objects.append(obj) @@ -392,6 +397,12 @@ class BuildPDF2XML(Command): if self.newer(dest, objects): cmd = ['g++', '-g', '-o', dest]+objects+['-lpoppler', '-lMagickWand', '-lpng', '-lpthread'] + if iswindows: + cmd = [msvc.linker] + '/INCREMENTAL:NO /DEBUG /NODEFAULTLIB:libcmt.lib'.split() + cmd += ['/LIBPATH:'+x for x in magick_lib_dirs+poppler_lib_dirs] + cmd += [x+'.lib' for x in + png_libs+magick_libs+poppler_libs+ft_libs+jpg_libs+pdfreflow_libs] + cmd += ['/OUT:'+dest] + objects self.info(*cmd) subprocess.check_call(cmd) diff --git a/setup/installer/windows/calibre/calibre.mpi b/setup/installer/windows/calibre/calibre.mpi index 860eae62f2..69a0dd771a 100644 --- a/setup/installer/windows/calibre/calibre.mpi +++ b/setup/installer/windows/calibre/calibre.mpi @@ -232,10 +232,6 @@ test } FileGroup ::BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows TarArchive ZipArchive FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -name {Program Files} -parent FileGroups File ::8E5D85A4-7608-47A1-CF7C-309060D5FF40 -filemethod {Always overwrite files} -type dir -directory <%InstallDir%> -name /home/kovid/work/calibre/build/py2exe -parent BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 -File ::FC870EE7-667B-481F-113B-B4504DFCCFA5 -type dir -name bin -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::377C588B-B324-CA09-ED49-4DB5F82A15ED -type dir -name etc -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::55DE4B9F-0881-FF51-E2BA-EC72B5D3425C -type dir -name fonts -parent 377C588B-B324-CA09-ED49-4DB5F82A15ED -File ::32D7DBE0-E0B1-5BDD-66C5-2A13D8BC8F90 -name fonts.conf -parent 55DE4B9F-0881-FF51-E2BA-EC72B5D3425C File ::B95D03D4-EA59-F00E-59E1-BA05758879DA -type dir -name imageformats -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::A624029D-AE0F-49A5-4DAC-7720CDCAB271 -name qmng4.dll -parent B95D03D4-EA59-F00E-59E1-BA05758879DA File ::C53E8AB9-30FC-730C-3DA3-851C9B4838A1 -name qmng4.exp -parent B95D03D4-EA59-F00E-59E1-BA05758879DA @@ -362,7 +358,6 @@ File ::A6419A84-6C22-784E-6D84-D09972770770 -name unicodedata.pyd -parent 8E5D85 File ::E658FBE0-5860-D041-12D3-76ADD18F804B -name servicemanager.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::C98A6FC4-E341-7FD4-005C-DA2B384E11D8 -name win32api.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::ADA36EEA-7DE1-447C-B1AB-A4908E65E2CD -name IM_MOD_RL_ipl_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::53C2EC15-850F-8F49-6425-C228FB6E6D0E -name libfontconfig-1.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::EDE6F457-C83F-C5FA-9AF4-38FDFF17D929 -name PIL._imagingtk.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::09D0906E-3611-3DB7-32CF-A140585694A7 -name win32pdh.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::4C84F0DC-7157-0C90-2062-180139B03E25 -name IM_MOD_RL_rgb_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 @@ -385,7 +380,6 @@ File ::404A98F1-84FD-B6D0-B130-354EECD9253C -name IM_MOD_RL_emf_.dll -parent 8E5 File ::17034C34-403E-B405-99C1-F80B7F00E27C -name log.xml -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::34E63A2C-65C5-0A84-ACF1-BD6A844D4579 -name pythoncom26.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::2F20484B-53B8-B08E-B691-C5B2D49A9CB4 -name QtWebKit4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::8AF134C8-9189-3F9A-A081-9143FFD44C45 -name freetype6.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::E8A4442D-D0D3-31CD-997A-3CEB641CF5B7 -name IM_MOD_RL_mtv_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::0CA87D0B-5A04-1439-AEE8-C97072D47BA7 -name CORE_RL_tiff_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::AC24F520-88D4-D1CF-5797-27C715CE8ACA -name pyexpat.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 @@ -564,11 +558,19 @@ File ::8D7A36A6-4517-E995-E989-2E522E7A1438 -name calibre-smtp.exe.local -parent File ::9E4E5E8F-30C0-E631-9516-2AE01A5CA0E9 -name ebook-device.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::7BE6B538-70D5-A7EB-5F91-E14CE57B394B -name calibre-complete.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::C4E40030-3EE0-8B05-E6B9-89E81433EE1F -name phonon4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::C9967023-A4C2-856C-1D90-DC710105EBCD -name jpeg62.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::B1560042-C99B-9803-552E-21C15F0DFD85 -type dir -name resources -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::DEDE8BE9-D712-2770-A1EC-7E9164CC6D29 -name libpng12.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::2A8619DB-B715-CBF8-E711-C6B0C5FD9EF4 -name _elementtree.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 -File ::0924A77D-EDD2-FF33-560A-983053637A47 -name libexpat-1.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::F92DE458-3417-3474-E0E0-C2CB98CA452A -name libxml2.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::5243CC78-8F58-46D6-4CDB-98FE073F4966 -name libxml2.dll.manifest -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::6C13AD7D-4C52-05F7-21D7-6258D4ECD542 -name freetype.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::800D9AFB-00CF-043C-0096-77BB4A2CD629 -name fontconfig.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::3B4975F7-B38C-895A-F11F-04BDF303309E -name jpeg.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::BA7F0DB8-28CB-9E0C-AA32-C10A729813D5 -name libexpatw.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::54736356-200D-EE7B-5D46-62B198B8AAF5 -name libexpat.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::9790CC7B-0491-AE6B-9E0D-98B046FB1352 -name poppler.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::620D5BA9-9652-2032-ED10-D3958F594AF4 -type dir -name fontconfig -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 +File ::57DAE30B-1BBA-0D0B-8DB0-DCE473520E9C -name zlib1.dll.manifest -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -name Main -parent Components SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -name Typical -parent SetupTypes diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py index 10bd05000b..46deea4661 100644 --- a/setup/installer/windows/freeze.py +++ b/setup/installer/windows/freeze.py @@ -9,13 +9,8 @@ Freeze app into executable using py2exe. QT_DIR = 'C:\\Qt\\4.5.2' LIBUSB_DIR = 'C:\\libusb' LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' -POPPLER = 'C:\\cygwin\\home\\kovid\\poppler\\poppler-build' -GNUWIN32 = r'C:\cygwin\home\kovid\gnuwin32' IMAGEMAGICK_DIR = 'C:\\ImageMagick' -PDFTK = 'C:\\pdftk.exe' -PODOFO = 'C:\\podofo' -FONTCONFIG_DIR = 'C:\\fontconfig' -VC90 = r'C:\VC90.CRT' +SW = r'C:\cygwin\home\kovid\sw' import sys @@ -193,36 +188,23 @@ class BuildEXE(bc): shutil.copyfile(f, os.path.join(tdir, os.path.basename(f))) print '\tAdding unrar' shutil.copyfile(LIBUNRAR, os.path.join(PY2EXE_DIR, os.path.basename(LIBUNRAR))) - print '\tAdding poppler' - for x in (r'pdftohtml.exe', 'freetype.dll'): - shutil.copyfile(os.path.join(r'C:\cygwin\home\kovid\poppler-old\bin', x), - os.path.join(PY2EXE_DIR, os.path.basename(x))) - for x in ('jpeg62', 'zlib1', 'libpng12'): - shutil.copy2(os.path.join(GNUWIN32, 'bin', x+'.dll'), PY2EXE_DIR) - print '\tAdding podofo' - for f in glob.glob(os.path.join(PODOFO, '*.dll')): - shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f))) - print '\tAdding ImageMagick' - for f in os.listdir(IMAGEMAGICK_DIR): - shutil.copyfile(os.path.join(IMAGEMAGICK_DIR, f), os.path.join(PY2EXE_DIR, f)) - print '\tCopying fontconfig' - for f in glob.glob(os.path.join(FONTCONFIG_DIR, '*')): - tgt = os.path.join(PY2EXE_DIR, os.path.basename(f)) - if os.path.isdir(f): - shutil.copytree(f, tgt) - else: - shutil.copyfile(f, tgt) + print '\tAdding misc binary deps' + bindir = os.path.join(SW, 'bin') + shutil.copy2(os.path.join(bindir, 'pdftohtml.exe'), PY2EXE_DIR) + for pat in ('*.dll', '*.xml'): + for f in glob.glob(os.path.join(bindir, pat)): + shutil.copy2(f, PY2EXE_DIR) + for x in ('Microsoft.VC90.CRT', 'zlib1.dll', 'libxml2.dll'): + shutil.copy2(os.path.join(bindir, x+'.manifest'), PY2EXE_DIR) + shutil.copytree(os.path.join(SW, 'etc', 'fonts'), + os.path.join(PY2EXE_DIR, 'fontconfig')) print print 'Doing DLL redirection' # See http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx for f in glob.glob(os.path.join(PY2EXE_DIR, '*.exe')): open(f + '.local', 'w').write('\n') - print - print 'Adding Windows runtime dependencies...' - for f in glob.glob(os.path.join(VC90, '*')): - shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f))) def exe_factory(dest_base, script, icon_resources=None): @@ -271,7 +253,7 @@ def main(args=sys.argv): 'email.iterators', 'email.generator', 'win32process', 'win32api', 'msvcrt', - 'win32event', 'calibre.ebooks.lrf.any.*', + 'win32event', 'sqlite3.dump', 'BeautifulSoup', 'pyreadline', 'pydoc', 'IPython.Extensions.*', diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst new file mode 100644 index 0000000000..9bacab4604 --- /dev/null +++ b/setup/installer/windows/notes.rst @@ -0,0 +1,167 @@ +Notes on setting up the windows development environment +======================================================== + +Set CMAKE_PREFIX_PATH to C:\cygwin\home\kovid\sw + +jpeg-7 +------- + +Copy +jconfig.vc to jconfig.h, makejsln.vc9 to jpeg.sln, +makeasln.vc9 to apps.sln, makejvcp.vc9 to jpeg.vcproj, +makecvcp.vc9 to cjpeg.vcproj, makedvcp.vc9 to djpeg.vcproj, +maketvcp.vc9 to jpegtran.vcproj, makervcp.vc9 to rdjpgcom.vcproj, and +makewvcp.vc9 to wrjpgcom.vcproj. (Note that the renaming is critical!) + +Load jpeg.sln in Visual Studio + +Goto Project->Properties->General Properties and change Configuration Type to dll + +Add + +#define USE_WINDOWS_MESSAGEBOX + +to jconfig.h (this will cause error messages to show up in a box) + +Change the definitions of GLOBAL and EXTERN in jmorecfg.h to +#define GLOBAL(type) __declspec(dllexport) type +#define EXTERN(type) extern __declspec(dllexport) type + +cp build/jpeg-7/Release/jpeg.dll bin/ +cp build/jpeg-7/Release/jpeg.lib build/jpeg-7/Release/jpeg.exp +cp build/jpeg-7/jerror.h build/jpeg-7/jpeglib.h build/jpeg-7/jconfig.h build/jpeg-7/jmorecfg.h include/ + +zlib +------ + +nmake -f win32/Makefile.msc +nmake -f win32/Makefile.msc test + +cp zlib1.dll* ../../bin +cp zlib.lib zdll.* ../../lib +cp zconf.h zlib.h ../../include + + +libpng +--------- + +cp scripts/CMakelists.txt . +mkdir build +Run cmake-gui.exe with source directory . and build directory build +You will have to point to sw/lib/zdll.lib and sw/include for zlib +Also disable PNG_NO_STDIO and PNG_NO_CONSOLE_IO + +Now open PNG.sln in VS2008 +Set Build type to Release + +cp build/libpng-1.2.40/build/Release/libpng12.dll bin/ +cp build/libpng-1.2.40/build/Release/png12.* lib/ +cp build/libpng-1.2.40/png.h build/libpng-1.2.40/pngconf.h include/ + +freetype +----------- + +Edit *all copies* of the file ftoption.h and add to generate a .lib +and a correct dll + +#define FT_EXPORT(return_type) __declspec(dllexport) return_type +#define FT_EXPORT_DEF(return_type) __declspec(dllexport) return_type + + +VS 2008 .sln file is present, open it + +Change active build type to release mutithreaded + +Project->Properties->Configuration Properties +change configuration type to dll + +cp build/freetype-2.3.9/objs/release_mt/freetype.dll bin/ + +Now change configuration back to static for .lib +cp build/freetype-2.3.9/objs/win32/vc2008/freetype239MT.lib lib/ +cp -rf build/freetype-2.3.9/include/* include/ + +expat +-------- + +Has a VC 6 project file expat.dsw + +Set active build to Relase and change build type to dll + +cp build/expat-2.0.1/win32/bin/Release/*.lib lib/ +cp build/expat-2.0.1/win32/bin/Release/*.exp lib/ +cp build/expat-2.0.1/win32/bin/Release/*.dll bin/ +cp build/expat-2.0.1/lib/expat.h build/expat-2.0.1/lib/expat_external.h include/ + +libxml2 +------------- + +cd win32 +cscript configure.js include=C:\cygwin\home\kovid\sw\include lib=C:\cygwin\home\sw\lib prefix=C:\cygwin\home\kovid\sw zlib=yes iconv=no +nmake /f Makefile.msvc +nmake /f Makefile.msvc install +mv lib/libxml2.dll bin/ +cp ./build/libxml2-2.7.5/win32/bin.msvc/*.manifest bin/ + +kdewin32-msvc +---------------- + +Get it from http://www.winkde.org/pub/kde/ports/win32/repository/kdesupport/ +mkdir build +Run cmake + +Set build type to release and configuration to dll + +Build + +cp build/kdewin32-msvc-0.3.9/build/include/* include/ +cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.dll bin/ +cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.lib lib/ +cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.exp lib/ +cp -r build/kdewin32-msvc-0.3.9/include/msvc/ include/ +cp build/kdewin32-msvc-0.3.9/include/*.h include/ + +fontconfig +--------------- + +Get it from http://www.winkde.org/pub/kde/ports/win32/repository/win32libs/ +mkdir build +Remove subdirectory test from the bottom of CMakeLists.txt +run cmake + +Set build type to release and project config to dll +Right click on the fontconfig project and select properties. Add sw/include/msvc to the include paths +Build only fontconfig + +cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.dll bin +cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.lib lib +cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.exp lib +cp -r build/fontconfig-msvc-2.4.2-3/fontconfig/ include/ + +Also install the etc files from the font-config-bin archive from kde win32libs +It contains correct fonts.conf etc. + + +poppler +------------- + +In Cmake: disable GTK, Qt, OPenjpeg, zlib, lcms, gtk_tests, qt_tests. Enable qt4, jpeg, png and zlib + +NOTE: poppler must be built as a static library, unless you build the qt4 bindings + +Now do the same for the pdftohtml project + +cp poppler/*.h ~/sw/include/poppler && cp goo/*.h ~/sw/include/poppler/goo && cp splash/*.h ~/sw/include/poppler/splash && cp build/Release/poppler.lib ../../lib/ && cp build/utils/Release/*.exe ../../bin/ + + +podofo +---------- + +Add the following three lines near the top of CMakeLists.txt +SET(WANT_LIB64 FALSE) +SET(PODOFO_BUILD_SHARED TRUE) +SET(PODOFO_BUILD_STATIC FALSE) + +cp build/podofo-0.7.0/build/src/Release/podofo.dll bin/ +cp build/podofo-0.7.0/build/src/Release/podofo.lib lib/ +cp build/podofo-0.7.0/build/src/Release/podofo.exp lib/ diff --git a/src/calibre/ebooks/pdf/main.cpp b/src/calibre/ebooks/pdf/main.cpp index 5102a5c774..e55edcae91 100644 --- a/src/calibre/ebooks/pdf/main.cpp +++ b/src/calibre/ebooks/pdf/main.cpp @@ -168,6 +168,8 @@ extern "C" { int main(int argc, char **argv) { char *memblock; ifstream::pos_type size; + int ret = 0; + if (argc != 2) { cerr << "Usage: " << argv[0] << " file.pdf" << endl; @@ -186,7 +188,6 @@ int main(int argc, char **argv) { return 1; } - int ret = 0; try { Reflow reflow(memblock, size); reflow.render(); diff --git a/src/calibre/ebooks/pdf/reflow.cpp b/src/calibre/ebooks/pdf/reflow.cpp index 86a33ced8e..cbd55f1fd2 100644 --- a/src/calibre/ebooks/pdf/reflow.cpp +++ b/src/calibre/ebooks/pdf/reflow.cpp @@ -149,7 +149,7 @@ string XMLString::str() const { } XMLString::~XMLString() { - delete this->text; delete this->x_right; + delete this->text; delete this->x_right; delete this->xml_text; } diff --git a/src/calibre/translations/zh_CN.po b/src/calibre/translations/zh_CN.po index cb807650c9..3c19858d1b 100644 --- a/src/calibre/translations/zh_CN.po +++ b/src/calibre/translations/zh_CN.po @@ -5807,7 +5807,7 @@ msgstr "开始转换 %d 本书" #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:64 #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:184 msgid "Convert book %d of %d (%s)" -msgstr "转换 %2$d 本书中的第 %1$d 本 (%s)" +msgstr "转换 %d 本书中的第 %d 本 (%s)" #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:91 #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:204 @@ -5819,7 +5819,7 @@ msgstr "无法转换某些书籍" msgid "" "Could not convert %d of %d books, because no suitable source format was " "found." -msgstr "由于未找到适用源格式,无法转换 %2$d 本书中的 %1$d 本。" +msgstr "由于未找到适用源格式,无法转换 %d 本书中的 %d 本。" #: /home/kovid/work/calibre/src/calibre/gui2/tools.py:123 msgid "Queueing books for bulk conversion" diff --git a/src/calibre/utils/fonts/Makefile.msvc b/src/calibre/utils/fonts/Makefile.msvc new file mode 100644 index 0000000000..b2c44895d3 --- /dev/null +++ b/src/calibre/utils/fonts/Makefile.msvc @@ -0,0 +1,2 @@ +winfonts.exe : winfonts.cpp + cl.exe /nologo /Ox /MD /W3 /EHsc winfonts.cpp diff --git a/src/calibre/utils/fonts/__init__.py b/src/calibre/utils/fonts/__init__.py index f4b4e0fc99..5cab0c4920 100644 --- a/src/calibre/utils/fonts/__init__.py +++ b/src/calibre/utils/fonts/__init__.py @@ -33,7 +33,7 @@ class FontConfig(Thread): config = os.path.join(config_dir, 'fonts.conf') if iswindows and getattr(sys, 'frozen', False): config_dir = os.path.join(os.path.dirname(sys.executable), - 'etc', 'fonts') + 'fontconfig') if isinstance(config_dir, unicode): config_dir = config_dir.encode(sys.getfilesystemencoding()) config = os.path.join(config_dir, 'fonts.conf') @@ -148,9 +148,10 @@ fontconfig.start() def test(): from pprint import pprint; - pprint(fontconfig.find_font_families()); - pprint(fontconfig.files_for_family('liberation serif')); - pprint(fontconfig.match('liberation serif:slant=italic:weight=bold', verbose=True)) + pprint(fontconfig.find_font_families()) + pprint(fontconfig.files_for_family('liberation serif')) + m = 'times new roman' if iswindows else 'liberation serif' + pprint(fontconfig.match(m+':slant=italic:weight=bold', verbose=True)) if __name__ == '__main__': test() diff --git a/src/calibre/utils/fonts/winfonts.cpp b/src/calibre/utils/fonts/winfonts.cpp new file mode 100644 index 0000000000..8bd2cc7c02 --- /dev/null +++ b/src/calibre/utils/fonts/winfonts.cpp @@ -0,0 +1,168 @@ +/* +:mod:`fontconfig` -- Pythonic interface to Windows font api +============================================================ + +.. module:: fontconfig + :platform: All + :synopsis: Pythonic interface to the fontconfig library + +.. moduleauthor:: Kovid Goyal Copyright 2009 + +*/ + +#define UNICODE +#include +#include +#include + +using namespace std; + +vector *get_font_data(HDC hdc) { + DWORD sz; + vector *data; + sz = GetFontData(hdc, 0, 0, NULL, 0); + data = new vector(sz); + if (GetFontData(hdc, 0, 0, &((*data)[0]), sz) == GDI_ERROR) { + delete data; data = NULL; + } + return data; + +} + +BOOL is_font_embeddable(ENUMLOGFONTEX *lpelfe) { + HDC hdc; + HFONT font; + HFONT old_font = NULL; + UINT sz; + size_t i; + LPOUTLINETEXTMETRICW metrics; + BOOL ans = TRUE; + hdc = GetDC(NULL); + font = CreateFontIndirect(&lpelfe->elfLogFont); + if (font != NULL) { + old_font = SelectObject(hdc, font); + sz = GetOutlineTextMetrics(hdc, 0, NULL); + metrics = new OUTLINETEXTMETRICW[sz]; + if ( GetOutlineTextMetrics(hdc, sz, metrics) != 0) { + for ( i = 0; i < sz; i++) { + if (metrics[i].otmfsType & 0x01) { + wprintf_s(L"Not embeddable: %s\n", lpelfe->elfLogFont.lfFaceName); + ans = FALSE; break; + } + } + } else ans = FALSE; + delete[] metrics; + DeleteObject(font); + SelectObject(hdc, old_font); + } else ans = FALSE; + ReleaseDC(NULL, hdc); + return ans; +} + +int CALLBACK find_families_callback ( + ENUMLOGFONTEX *lpelfe, /* pointer to logical-font data */ + NEWTEXTMETRICEX *lpntme, /* pointer to physical-font data */ + int FontType, /* type of font */ + LPARAM lParam /* a combo box HWND */ + ) { + size_t i; + LPWSTR tmp; + vector *families = (vector*)lParam; + + if (FontType & TRUETYPE_FONTTYPE) { + for (i = 0; i < families->size(); i++) { + if (lstrcmp(families->at(i), lpelfe->elfLogFont.lfFaceName) == 0) + return 1; + } + tmp = new WCHAR[LF_FACESIZE]; + swprintf_s(tmp, LF_FACESIZE, L"%s", lpelfe->elfLogFont.lfFaceName); + families->push_back(tmp); + } + + return 1; +} + + +vector* find_font_families(void) { + LOGFONTW logfont; + HDC hdc; + vector *families; + + families = new vector(); + SecureZeroMemory(&logfont, sizeof(logfont)); + + logfont.lfCharSet = DEFAULT_CHARSET; + logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE; + StringCchCopyW(logfont.lfFaceName, 2, L"\0"); + + hdc = GetDC(NULL); + EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROC)find_families_callback, + (LPARAM)(families), 0); + + ReleaseDC(NULL, hdc); + + return families; +} + +inline void free_families_vector(vector *v) { + for (size_t i = 0; i < v->size(); i++) delete[] v->at(i); + delete v; +} + +#ifdef TEST + +int main(int argc, char **argv) { + vector *all_families; + size_t i; + + all_families = find_font_families(); + + for (i = 0; i < all_families->size(); i++) + wprintf_s(L"%s\n", all_families->at(i)); + + free_families_vector(all_families); + + HDC hdc = GetDC(NULL); + HFONT font = CreateFont(72,0,0,0,0,0,0,0,0,0,0,0,0,L"Verdana"); + HFONT old_font = SelectObject(hdc, font); + vector *data = get_font_data(hdc); + DeleteObject(font); + SelectObject(hdc, old_font); + ReleaseDC(NULL, hdc); + if (data != NULL) printf("\nyay: %d\n", data->size()); + delete data; + + return 0; +} +#else + +#define PY_SSIZE_T_CLEAN +#include +# + +static +PyMethodDef fontconfig_methods[] = { + {"find_font_families", fontconfig_find_font_families, METH_VARARGS, + "find_font_families(allowed_extensions)\n\n" + "Find all font families on the system for fonts of the specified types. If no " + "types are specified all font families are returned." + }, + + + {NULL, NULL, 0, NULL} +}; + + +extern "C" { +PyMODINIT_FUNC +initfontconfig(void) { + PyObject *m; + m = Py_InitModule3( + "fontconfig", fontconfig_methods, + "Find fonts." + ); + if (m == NULL) return; +} +} + +#endif