Re: [poppler] qt4/src/poppler-qiodeviceoutstream.cc: open_memstream is non-portable
On 28 Jan 2008, at 10:53 pm, Kristian Høgsberg wrote: On Jan 28, 2008 5:20 PM, Albert Astals Cid <[EMAIL PROTECTED]> wrote: A Dilluns 28 Gener 2008, Jonathan Kew va escriure: The document saving code in the Qt4 wrapper uses open_memstream(), which is not available on all platforms. I would recommend using vasprintf() instead, which I suspect is more widely supported, but this is also a GNU extension and may not be available everywhere. So a fallback approach using vsnprintf() is also needed. Proposed changes below I'll let Pino comment on that, but he is travelling so it'll take a while. I'll weigh in though and say that using open_memstream() isn't acceptable, it's very GNU Libc specific. Also, the suggested patch has the same problems as the strndup() patch. I'm sure there is a helper function in Qt to create a dynamically allocated string from a printf-style string, that would be the way to go. Attached is a revised (and simplified) version of the patch, abandoning open_memstream() etc in favor of QString::vsprintf(), which seems to be the Qt4 way to do this. I suppose this means that the string is being (unnecessarily) converted to and from Unicode, which may introduce a little overhead, but I doubt this is a performance-critical point. JK diff --git a/qt4/src/poppler-qiodeviceoutstream.cc b/qt4/src/poppler-qiodeviceoutstream.cc index 11fab97..4716952 100644 --- a/qt4/src/poppler-qiodeviceoutstream.cc +++ b/qt4/src/poppler-qiodeviceoutstream.cc @@ -58,14 +58,11 @@ void QIODeviceOutStream::printf(const char *format, ...) { va_list ap; va_start(ap, format); - char* buf = 0; - size_t bufsize = 0; - FILE* stream = open_memstream(&buf, &bufsize); - vfprintf(stream, format, ap); + QString s; + s.vsprintf(format, ap); va_end(ap); - fclose(stream); - m_device->write(buf, bufsize); - free(buf); + QByteArray ba = s.toAscii(); + m_device->write(ba.constData(), ba.size()); } } ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
[poppler] 2 commits - poppler/SplashOutputDev.cc qt4/tests splash/SplashFontFile.cc splash/SplashFontFile.h splash/SplashFont.h splash/SplashFTFont.cc splash/SplashFTFont.h
poppler/SplashOutputDev.cc | 37 +++ qt4/tests/test-poppler-qt4.cpp |2 + splash/SplashFTFont.cc | 55 - splash/SplashFTFont.h |4 ++ splash/SplashFont.h|4 ++ splash/SplashFontFile.cc |1 splash/SplashFontFile.h|2 + 7 files changed, 104 insertions(+), 1 deletion(-) New commits: commit 4c738cc6bd51f9d9e23ba83949c490c5c8691345 Author: Albert Astals Cid <[EMAIL PROTECTED]> Date: Tue Jan 29 23:45:52 2008 +0100 Scale text to match 'm' size Fixes bug 12304 diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index c810dc7..5315bfc 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -965,6 +965,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) { SplashCoord mat[4]; int substIdx, n; int faceIndex = 0; + GBool recreateFont = gFalse; needFontUpdate = gFalse; font = NULL; @@ -1142,6 +1143,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) { // this shouldn't happen goto err2; } +fontFile->doAdjustMatrix = gTrue; } // get the font matrix @@ -1157,6 +1159,41 @@ void SplashOutputDev::doUpdateFont(GfxState *state) { mat[2] = m21; mat[3] = m22; font = fontEngine->getFont(fontFile, mat, splash->getMatrix()); + // for substituted fonts: adjust the font matrix -- compare the + // width of 'm' in the original font and the substituted font + if (fontFile->doAdjustMatrix && !gfxFont->isCIDFont()) { +double w1, w2; +CharCode code; +char *name; +for (code = 0; code < 256; ++code) { + if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) && + name[0] == 'm' && name[1] == '\0') { +break; + } +} +if (code < 256) { + w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code); + w2 = font->getGlyphAdvance(code); + if (!gfxFont->isSymbolic() && w2 > 0) { +// if real font is substantially narrower than substituted +// font, reduce the font size accordingly +if (w1 > 0.01 && w1 < 0.9 * w2) { + w1 /= w2; + m11 *= w1; + m21 *= w1; + recreateFont = gTrue; +} + } +} + } + + if (recreateFont) + { +mat[0] = m11; mat[1] = m12; +mat[2] = m21; mat[3] = m22; +font = fontEngine->getFont(fontFile, mat, splash->getMatrix()); + } + if (fontsrc && !fontsrc->isFile) fontsrc->unref(); return; diff --git a/splash/SplashFTFont.cc b/splash/SplashFTFont.cc index 0241df0..28e48d7 100644 --- a/splash/SplashFTFont.cc +++ b/splash/SplashFTFont.cc @@ -42,7 +42,7 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA, SplashFont(fontFileA, matA, textMatA, fontFileA->engine->aa) { FT_Face face; - double size, div; + double div; int x, y; face = fontFileA->face; @@ -239,6 +239,59 @@ GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac, return gTrue; } +double SplashFTFont::getGlyphAdvance(int c) +{ + SplashFTFontFile *ff; + FT_Vector offset; + FT_UInt gid; + FT_Matrix identityMatrix; + + ff = (SplashFTFontFile *)fontFile; + + // init the matrix + identityMatrix.xx = 65536; // 1 in 16.16 format + identityMatrix.xy = 0; + identityMatrix.yx = 0; + identityMatrix.yy = 65536; // 1 in 16.16 format + + // init the offset + offset.x = 0; + offset.y = 0; + + FT_Set_Transform(ff->face, &identityMatrix, &offset); + + if (ff->codeToGID && c < ff->codeToGIDLen) { +gid = (FT_UInt)ff->codeToGID[c]; + } else { +gid = (FT_UInt)c; + } + if (ff->trueType && gid == 0) { +// skip the TrueType notdef glyph +return -1; + } + + // if we have the FT2 bytecode interpreter, autohinting won't be used +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + if (FT_Load_Glyph(ff->face, gid, + aa ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT)) { +return -1; + } +#else + // FT2's autohinting doesn't always work very well (especially with + // font subsets), so turn it off if anti-aliasing is enabled; if + // anti-aliasing is disabled, this seems to be a tossup - some fonts + // look better with hinting, some without, so leave hinting on + if (FT_Load_Glyph(ff->face, gid, + aa ? FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP + : FT_LOAD_DEFAULT)) { +return -1; + } +#endif + + // 64.0 is 1 in 26.6 format + return ff->face->glyph->metrics.horiAdvance / 64.0 / size; +} + struct SplashFTFontPath { SplashPath *path; SplashCoord textScale; diff --git a/splash/SplashFTFont.h b/splash/SplashFTFont.h index 70c01d3..4e22026 100644 --- a/splash/SplashFTFont.h +++ b/splash/SplashFTFont.h @@ -43,12 +43,16 @@ public: // Return the path for a glyph. virtual SplashPath *getGlyphPath(int c); + // Return the advance of a glyph. (in 0..1 range) + virtual double getGlyphAdvance(int c); + private: FT_Size sizeObj; FT_Matrix matrix;
Re: [poppler] saving a form
El mar, 29-01-2008 a las 20:31 +0100, Albert Astals Cid escribió: > A Diumenge 27 Gener 2008, Carlos Garcia Campos va escriure: > > Hi all, > > > > I've noticed that right now, saveAs will always save the changes of an > > already filled form so that it's impossible to save a copy of the pdf > > document without saving the contents of the form fields.You would have > > to manually reset the form, or close the document and reopen it again. I > > think there are (at least) two possible solutions: > > > > * Adding a new write method to saveAs > > When you say method you mean a new PDFWriteMode enum value? yes, of course I meant mode instead of method :-P > I would disagree > to that because the current enum values have nothing to do with what is > saved, they are about how it's saved, and mixing them seems quite weird. agree > > * Adding a new method saveACopy that never saves the changes and would > > be used by saveAs when the write method is Standard and there are no > > changes. > > What about saveUnchangedCopy or saveCopyWithoutChanges? I think that's ok. > > BTW, just to be sure if the document originally has values on the forms, > saveACopy/saveUnchangedCopy/saveCopyWithoutChanges will still leave them > there, right? yes, of course. > Albert > > > ___ > poppler mailing list > poppler@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler -- Carlos Garcia Campos [EMAIL PROTECTED] [EMAIL PROTECTED] http://carlosgc.linups.org PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462 signature.asc Description: Esta parte del mensaje está firmada digitalmente ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
Re: [poppler] strndup - updated
On Jan 29, 2008 10:32 AM, Jonathan Kew <[EMAIL PROTECTED]> wrote: > > On 28 Jan 2008, at 10:45 pm, Kristian Høgsberg wrote: > > > >> The right fix is to split the > >> code out into its own function and put it in goo/gmem.c along with > >> the > >> other memory/string functions there. > > > > Attached is a patch that gets rid of the offending #ifdef, and uses a > new gstrndup function instead. (This also has the side effect of > removing the pre-existing strndup/gfree bug.) That looks good, thanks. Kristian ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
Re: [poppler] saving a form
A Diumenge 27 Gener 2008, Carlos Garcia Campos va escriure: > Hi all, > > I've noticed that right now, saveAs will always save the changes of an > already filled form so that it's impossible to save a copy of the pdf > document without saving the contents of the form fields. You would have > to manually reset the form, or close the document and reopen it again. I > think there are (at least) two possible solutions: > > * Adding a new write method to saveAs When you say method you mean a new PDFWriteMode enum value? I would disagree to that because the current enum values have nothing to do with what is saved, they are about how it's saved, and mixing them seems quite weird. > * Adding a new method saveACopy that never saves the changes and would > be used by saveAs when the write method is Standard and there are no > changes. What about saveUnchangedCopy or saveCopyWithoutChanges? I think that's ok. BTW, just to be sure if the document originally has values on the forms, saveACopy/saveUnchangedCopy/saveCopyWithoutChanges will still leave them there, right? Albert ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
Re: [poppler] strndup - updated
A Dimarts 29 Gener 2008, Jonathan Kew va escriure: > > On 28 Jan 2008, at 10:45 pm, Kristian Høgsberg wrote: > >> The right fix is to split the > >> code out into its own function and put it in goo/gmem.c along with > >> the > >> other memory/string functions there. > > Attached is a patch that gets rid of the offending #ifdef, and uses a > new gstrndup function instead. (This also has the side effect of > removing the pre-existing strndup/gfree bug.) > > JK Applied thanks. Albert ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
[poppler] configure.ac goo/gmem.cc goo/gmem.h poppler/GfxFont.cc
configure.ac |1 - goo/gmem.cc|7 +++ goo/gmem.h |5 + poppler/GfxFont.cc |8 +--- 4 files changed, 13 insertions(+), 8 deletions(-) New commits: commit 90f0e6bc1e96d9f1666cb8476a92e127f5b927d4 Author: Jonathan Kew <[EMAIL PROTECTED]> Date: Tue Jan 29 20:23:08 2008 +0100 Provide gstrndup as a portable substitue of strndup diff --git a/configure.ac b/configure.ac index dd56ea4..99ffbda 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,6 @@ AC_PROG_CXX AC_PROG_INSTALL AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Defines if gettimeofday is available on your system])) AC_CHECK_FUNC(localtime_r, AC_DEFINE(HAVE_LOCALTIME_R, 1, [Defines if localtime_r is available on your system])) -AC_CHECK_FUNC(strndup, AC_DEFINE(HAVE_STRNDUP, 1, [Defines if strndup is available on your system])) dnl Enable these unconditionally. AC_DEFINE([OPI_SUPPORT], [1], [Generate OPI comments in PS output.]) diff --git a/goo/gmem.cc b/goo/gmem.cc index 3dce8ea..b11f2f4 100644 --- a/goo/gmem.cc +++ b/goo/gmem.cc @@ -280,3 +280,10 @@ char *copyString(char *s) { strcpy(s1, s); return s1; } + +char *gstrndup(const char *s, size_t n) { + char *s1 = (char*)gmalloc(n + 1); /* cannot return NULL for size > 0 */ + s1[n] = '\0'; + memcpy(s1, s, n); + return s1; +} diff --git a/goo/gmem.h b/goo/gmem.h index 39c2334..b1d175d 100644 --- a/goo/gmem.h +++ b/goo/gmem.h @@ -75,6 +75,11 @@ extern void gMemReport(FILE *f); */ extern char *copyString(char *s); +/* + * Allocate memory and copy a limited-length string to it. + */ +extern char *gstrndup(const char *s, size_t n); + #ifdef __cplusplus } #endif diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc index 533904b..2d9abd4 100644 --- a/poppler/GfxFont.cc +++ b/poppler/GfxFont.cc @@ -974,13 +974,7 @@ static int parseCharName(char *charName, Unicode *uBuf, int uLen, return 0;// .notdef or similar } else if (var_part != NULL) { // parse names of the form 7.oldstyle, P.swash, s.sc, etc. -#ifdef HAVE_STRNDUP - char *main_part = strndup(charName, var_part - charName); -#else - char *main_part = (char*)gmalloc(var_part - charName + 1); - main_part[var_part - charName] = '\0'; - memcpy(main_part, charName, var_part - charName); -#endif + char *main_part = gstrndup(charName, var_part - charName); GBool namesRecurse = gTrue, variantsRecurse = gFalse; int n = parseCharName(main_part, uBuf, uLen, namesRecurse, ligatures, numeric, hex, variantsRecurse); ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler
Re: [poppler] strndup - updated
On 28 Jan 2008, at 10:45 pm, Kristian Høgsberg wrote: The right fix is to split the code out into its own function and put it in goo/gmem.c along with the other memory/string functions there. Attached is a patch that gets rid of the offending #ifdef, and uses a new gstrndup function instead. (This also has the side effect of removing the pre-existing strndup/gfree bug.) JK diff --git a/configure.ac b/configure.ac index dd56ea4..99ffbda 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,6 @@ AC_PROG_CXX AC_PROG_INSTALL AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Defines if gettimeofday is available on your system])) AC_CHECK_FUNC(localtime_r, AC_DEFINE(HAVE_LOCALTIME_R, 1, [Defines if localtime_r is available on your system])) -AC_CHECK_FUNC(strndup, AC_DEFINE(HAVE_STRNDUP, 1, [Defines if strndup is available on your system])) dnl Enable these unconditionally. AC_DEFINE([OPI_SUPPORT], [1], [Generate OPI comments in PS output.]) diff --git a/goo/gmem.cc b/goo/gmem.cc index 3dce8ea..b11f2f4 100644 --- a/goo/gmem.cc +++ b/goo/gmem.cc @@ -280,3 +280,10 @@ char *copyString(char *s) { strcpy(s1, s); return s1; } + +char *gstrndup(const char *s, size_t n) { + char *s1 = (char*)gmalloc(n + 1); /* cannot return NULL for size > 0 */ + s1[n] = '\0'; + memcpy(s1, s, n); + return s1; +} diff --git a/goo/gmem.h b/goo/gmem.h index 39c2334..b1d175d 100644 --- a/goo/gmem.h +++ b/goo/gmem.h @@ -75,6 +75,11 @@ extern void gMemReport(FILE *f); */ extern char *copyString(char *s); +/* + * Allocate memory and copy a limited-length string to it. + */ +extern char *gstrndup(const char *s, size_t n); + #ifdef __cplusplus } #endif diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc index 533904b..2d9abd4 100644 --- a/poppler/GfxFont.cc +++ b/poppler/GfxFont.cc @@ -974,13 +974,7 @@ static int parseCharName(char *charName, Unicode *uBuf, int uLen, return 0;// .notdef or similar } else if (var_part != NULL) { // parse names of the form 7.oldstyle, P.swash, s.sc, etc. -#ifdef HAVE_STRNDUP - char *main_part = strndup(charName, var_part - charName); -#else - char *main_part = (char*)gmalloc(var_part - charName + 1); - main_part[var_part - charName] = '\0'; - memcpy(main_part, charName, var_part - charName); -#endif + char *main_part = gstrndup(charName, var_part - charName); GBool namesRecurse = gTrue, variantsRecurse = gFalse; int n = parseCharName(main_part, uBuf, uLen, namesRecurse, ligatures, numeric, hex, variantsRecurse); ___ poppler mailing list poppler@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler