Am 19.03.2012 08:05, schrieb Thomas Freitag:
Am 16.03.2012 16:08, schrieb Carlos Garcia Campos:
Excerpts from Albert Astals Cid's message of jue mar 15 22:23:15 +0100 2012:
Available from
http://poppler.freedesktop.org/poppler-0.19.1.tar.gz
WARNING: This is a unstable release, it is actually 0.20 Beta 1 release, it
should work like any release from the 0.18 branch, but do not blame us if it
turns your cat into a lion and eats your breakfast.
Changes against the 0.19.0 branch:
core:
* Improve CJK suport in PSOutputDev
* CJK substitute implementation on WIndows platforms
* Do not crash on malformed files with 0 bits in the color map of an image
* Fix regression in some PSOutputDev array sizing
* Improvements to Annotation editing
* Fix logic error in Rendition parsing code (Bug #47063)
* Minor API changes to SplashOutputDev (Bug #46622)
* Fix mismatch in some functions declarations
* Update poppler copyright year
utils:
* pdftops: Fix -passfonts regression. (Bug #46744)
* pdffonts: List the encoding of each font. (Bug #46888)
* pdftohtml: Add possibilty of controlling word breaks percentage. (Bug
#47022)
qt4:
* Support for LinkMovie object (Bug #40561)
* Support for Media Rendition
glib:
* Add poppler_fonts_iter_get_encoding
* Improvements to the demo
Testing, patches and bug reports welcome.
My TODO list is:
* Work with Fabio in his Annot Qt4 patches
* Decide something with Adrian in the "Pdf that uses the symbol font" thread
* Review 47186 pdftohtml: mask images are not extracted, unless they are JPEG
* Review 32340 pdftohtml: renders images vertically flipped
Remember feature freeze is in 2 weeks with Beta 2
If anyone has anything else that thinks it is waiting on me for further
feedback, tellme, because it's not on my list
The xpdf303 merge introduced some regressions in the cairo backend,
I'll try to find some time this weekend to send more details to the list.
I just finished the patch for these regressions, they had differents reasons
1. In CharCodeToUnicode::mapToUnicode the identity support was missing
2. The new algorithms for axial and radial shading caused problems in
cairo. I revert these changes but removed the examination of hidden
content (this is already done in the calling function)
3. The examination of optional hidden content in showing text was wrong:
of course hidden text should not be shown, but text parameters like text
position in the state must be changed!
4. Searching and finding fonts especially with base14 fonts should be
more exact than just looking at the base14 name (i.e. fixed width and so
on) when using fontconfig. I implement that to find the best font
fitting to the needs.
Cheers,
Thomas
Albert
Thanks,
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler
diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc
index 076f5ba..afcf4c2 100644
--- a/poppler/CharCodeToUnicode.cc
+++ b/poppler/CharCodeToUnicode.cc
@@ -621,6 +621,10 @@ int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode **u) {
int CharCodeToUnicode::mapToCharCode(Unicode* u, CharCode *c, int usize) {
//look for charcode in map
if (usize == 1) {
+ if (isIdentity) {
+ *c = (CharCode) *u;
+ return 1;
+ }
for (CharCode i=0; i<mapLen; i++) {
if (map[i] == *u) {
*c = i;
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 2cc8e28..bd59dd2 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2576,10 +2576,10 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
double xMin, yMin, xMax, yMax;
double x0, y0, x1, y1;
double dx, dy, mul;
- GBool dxdyZero, horiz;
+ GBool dxZero, dyZero;
double bboxIntersections[4];
double tMin, tMax, tx, ty;
- double sMin, sMax, tmp;
+ double s[4], sMin, sMax, tmp;
double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
double t0, t1, tt;
double ta[axialMaxSplits + 1];
@@ -2597,9 +2597,9 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
shading->getCoords(&x0, &y0, &x1, &y1);
dx = x1 - x0;
dy = y1 - y0;
- dxdyZero = fabs(dx) < 0.01 && fabs(dy) < 0.01;
- horiz = fabs(dy) < fabs(dx);
- if (dxdyZero) {
+ dxZero = fabs(dx) < 0.01;
+ dyZero = fabs(dy) < 0.01;
+ if (dxZero && dyZero) {
tMin = tMax = 0;
} else {
mul = 1 / (dx * dx + dy * dy);
@@ -2636,16 +2636,18 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// y(s) = ty + s * dx --> s = (y - ty) / dx
//
// Then look at the intersection of this line with the bounding box
- // (xMin, yMin, xMax, yMax). For -1 < |dy/dx| < 1, look at the
- // intersection with yMin, yMax:
- //
- // s0 = (yMin - ty) / dx
- // s1 = (yMax - ty) / dx
- //
- // else look at the intersection with xMin, xMax:
+ // (xMin, yMin, xMax, yMax). In the general case, there are four
+ // intersection points:
//
// s0 = (xMin - tx) / -dy
// s1 = (xMax - tx) / -dy
+ // s2 = (yMin - ty) / dx
+ // s3 = (yMax - ty) / dx
+ //
+ // and we want the middle two s values.
+ //
+ // In the case where dx = 0, take s0 and s1; in the case where dy =
+ // 0, take s2 and s3.
//
// Each filled polygon is bounded by two of these line segments
// perpdendicular to the t axis.
@@ -2654,10 +2656,13 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// difference across a region is small enough, and then the region
// is painted with a single color.
- // set up
+ // set up: require at least one split to avoid problems when the two
+ // ends of the t axis have the same color
nComps = shading->getColorSpace()->getNComps();
ta[0] = tMin;
- next[0] = axialMaxSplits;
+ next[0] = axialMaxSplits / 2;
+ ta[axialMaxSplits / 2] = 0.5 * (tMin + tMax);
+ next[axialMaxSplits / 2] = axialMaxSplits;
ta[axialMaxSplits] = tMax;
// compute the color at t = tMin
@@ -2681,19 +2686,24 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// bounding box
tx = x0 + tMin * dx;
ty = y0 + tMin * dy;
- if (dxdyZero) {
+ if (dxZero && dyZero) {
sMin = sMax = 0;
+ } else if (dxZero) {
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else if (dyZero) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
} else {
- if (horiz) {
- sMin = (yMin - ty) / dx;
- sMax = (yMax - ty) / dx;
- } else {
- sMin = (xMin - tx) / -dy;
- sMax = (xMax - tx) / -dy;
- }
- if (sMin > sMax) {
- tmp = sMin; sMin = sMax; sMax = tmp;
- }
+ s[0] = (yMin - ty) / dx;
+ s[1] = (yMax - ty) / dx;
+ s[2] = (xMin - tx) / -dy;
+ s[3] = (xMax - tx) / -dy;
+ bubbleSort(s);
+ sMin = s[1];
+ sMax = s[2];
}
ux0 = tx - sMin * dy;
uy0 = ty + sMin * dx;
@@ -2702,7 +2712,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
i = 0;
bool doneBBox1, doneBBox2;
- if (dxdyZero) {
+ if (dxZero && dyZero) {
doneBBox1 = doneBBox2 = true;
} else {
doneBBox1 = bboxIntersections[1] < tMin;
@@ -2782,21 +2792,24 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// bounding box
tx = x0 + ta[j] * dx;
ty = y0 + ta[j] * dy;
- tx = x0 + ta[j] * dx;
- ty = y0 + ta[j] * dy;
- if (dxdyZero) {
+ if (dxZero && dyZero) {
sMin = sMax = 0;
+ } else if (dxZero) {
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else if (dyZero) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
} else {
- if (horiz) {
- sMin = (yMin - ty) / dx;
- sMax = (yMax - ty) / dx;
- } else {
- sMin = (xMin - tx) / -dy;
- sMax = (xMax - tx) / -dy;
- }
- if (sMin > sMax) {
- tmp = sMin; sMin = sMax; sMax = tmp;
- }
+ s[0] = (yMin - ty) / dx;
+ s[1] = (yMax - ty) / dx;
+ s[2] = (xMin - tx) / -dy;
+ s[3] = (xMax - tx) / -dy;
+ bubbleSort(s);
+ sMin = s[1];
+ sMax = s[2];
}
ux1 = tx - sMin * dy;
uy1 = ty + sMin * dx;
@@ -2874,10 +2887,7 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
GfxColor colorA, colorB;
double xa, ya, xb, yb, ra, rb;
double ta, tb, sa, sb;
- double sMin, sMax, h;
- double sLeft, sRight, sTop, sBottom, sZero, sDiag;
- GBool haveSLeft, haveSRight, haveSTop, haveSBottom, haveSZero;
- GBool haveSMin, haveSMax;
+ double sz, xz, yz, sMin, sMax;
GBool enclosed;
int ia, ib, k, n;
double *ctm;
@@ -2892,21 +2902,24 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
// Compute the point at which r(s) = 0; check for the enclosed
// circles case; and compute the angles for the tangent lines.
- h = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
- if (h == 0) {
+ if (x0 == x1 && y0 == y1) {
enclosed = gTrue;
theta = 0; // make gcc happy
- } else if (r1 - r0 == 0) {
+ sz = 0; // make gcc happy
+ } else if (r0 == r1) {
enclosed = gFalse;
theta = 0;
- } else if (fabs(r1 - r0) >= h) {
- enclosed = gTrue;
- theta = 0; // make gcc happy
+ sz = 0; // make gcc happy
} else {
- enclosed = gFalse;
- theta = asin((r1 - r0) / h);
+ sz = (r1 > r0) ? -r0 / (r1 - r0) : -r1 / (r0 - r1);
+ xz = x0 + sz * (x1 - x0);
+ yz = y0 + sz * (y1 - y0);
+ enclosed = (xz - x0) * (xz - x0) + (yz - y0) * (yz - y0) <= r0 * r0;
+ theta = asin(r0 / sqrt((x0 - xz) * (x0 - xz) + (y0 - yz) * (y0 - yz)));
+ if (r0 > r1) {
+ theta = -theta;
+ }
}
-
if (enclosed) {
alpha = 0;
} else {
@@ -2919,101 +2932,59 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
sMin = 0;
sMax = 1;
} else {
- // solve x(sLeft) + r(sLeft) = xMin
- if ((haveSLeft = fabs((x1 + r1) - (x0 + r0)) > 0.000001)) {
- sLeft = (xMin - (x0 + r0)) / ((x1 + r1) - (x0 + r0));
- } else {
- sLeft = 0; // make gcc happy
- }
- // solve x(sRight) - r(sRight) = xMax
- if ((haveSRight = fabs((x1 - r1) - (x0 - r0)) > 0.000001)) {
- sRight = (xMax - (x0 - r0)) / ((x1 - r1) - (x0 - r0));
- } else {
- sRight = 0; // make gcc happy
- }
- // solve y(sBottom) + r(sBottom) = yMin
- if ((haveSBottom = fabs((y1 + r1) - (y0 + r0)) > 0.000001)) {
- sBottom = (yMin - (y0 + r0)) / ((y1 + r1) - (y0 + r0));
- } else {
- sBottom = 0; // make gcc happy
- }
- // solve y(sTop) - r(sTop) = yMax
- if ((haveSTop = fabs((y1 - r1) - (y0 - r0)) > 0.000001)) {
- sTop = (yMax - (y0 - r0)) / ((y1 - r1) - (y0 - r0));
- } else {
- sTop = 0; // make gcc happy
+ sMin = 1;
+ sMax = 0;
+ // solve for x(s) + r(s) = xMin
+ if ((x1 + r1) - (x0 + r0) != 0) {
+ sa = (xMin - (x0 + r0)) / ((x1 + r1) - (x0 + r0));
+ if (sa < sMin) {
+ sMin = sa;
+ } else if (sa > sMax) {
+ sMax = sa;
+ }
}
- // solve r(sZero) = 0
- if ((haveSZero = fabs(r1 - r0) > 0.000001)) {
- sZero = -r0 / (r1 - r0);
- } else {
- sZero = 0; // make gcc happy
+ // solve for x(s) - r(s) = xMax
+ if ((x1 - r1) - (x0 - r0) != 0) {
+ sa = (xMax - (x0 - r0)) / ((x1 - r1) - (x0 - r0));
+ if (sa < sMin) {
+ sMin = sa;
+ } else if (sa > sMax) {
+ sMax = sa;
+ }
}
- // solve r(sDiag) = sqrt((xMax-xMin)^2 + (yMax-yMin)^2)
- if (haveSZero) {
- sDiag = (sqrt((xMax - xMin) * (xMax - xMin) +
- (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0);
- } else {
- sDiag = 0; // make gcc happy
+ // solve for y(s) + r(s) = yMin
+ if ((y1 + r1) - (y0 + r0) != 0) {
+ sa = (yMin - (y0 + r0)) / ((y1 + r1) - (y0 + r0));
+ if (sa < sMin) {
+ sMin = sa;
+ } else if (sa > sMax) {
+ sMax = sa;
+ }
}
- // compute sMin
- if (shading->getExtend0()) {
- sMin = 0;
- haveSMin = gFalse;
- if (x0 < x1 && haveSLeft && sLeft < 0) {
- sMin = sLeft;
- haveSMin = gTrue;
- } else if (x0 > x1 && haveSRight && sRight < 0) {
- sMin = sRight;
- haveSMin = gTrue;
+ // solve for y(s) - r(s) = yMax
+ if ((y1 - r1) - (y0 - r0) != 0) {
+ sa = (yMax - (y0 - r0)) / ((y1 - r1) - (y0 - r0));
+ if (sa < sMin) {
+ sMin = sa;
+ } else if (sa > sMax) {
+ sMax = sa;
}
- if (y0 < y1 && haveSBottom && sBottom < 0) {
- if (!haveSMin || sBottom > sMin) {
- sMin = sBottom;
- haveSMin = gTrue;
- }
- } else if (y0 > y1 && haveSTop && sTop < 0) {
- if (!haveSMin || sTop > sMin) {
- sMin = sTop;
- haveSMin = gTrue;
- }
+ }
+ // check against sz
+ if (r0 < r1) {
+ if (sMin < sz) {
+ sMin = sz;
}
- if (haveSZero && sZero < 0) {
- if (!haveSMin || sZero > sMin) {
- sMin = sZero;
- }
+ } else if (r0 > r1) {
+ if (sMax > sz) {
+ sMax = sz;
}
- } else {
+ }
+ // check the 'extend' flags
+ if (!shading->getExtend0() && sMin < 0) {
sMin = 0;
}
- // compute sMax
- if (shading->getExtend1()) {
- sMax = 1;
- haveSMax = gFalse;
- if (x1 < x0 && haveSLeft && sLeft > 1) {
- sMax = sLeft;
- haveSMax = gTrue;
- } else if (x1 > x0 && haveSRight && sRight > 1) {
- sMax = sRight;
- haveSMax = gTrue;
- }
- if (y1 < y0 && haveSBottom && sBottom > 1) {
- if (!haveSMax || sBottom < sMax) {
- sMax = sBottom;
- haveSMax = gTrue;
- }
- } else if (y1 > y0 && haveSTop && sTop > 1) {
- if (!haveSMax || sTop < sMax) {
- sMax = sTop;
- haveSMax = gTrue;
- }
- }
- if (haveSZero && sDiag > 1) {
- if (!haveSMax || sDiag < sMax) {
- sMax = sDiag;
- }
- }
- } else {
+ if (!shading->getExtend1() && sMax > 1) {
sMax = 1;
}
}
@@ -3758,11 +3729,10 @@ void Gfx::opShowText(Object args[], int numArgs) {
out->updateFont(state);
fontChanged = gFalse;
}
- if (ocState) {
- out->beginStringOp(state);
- doShowText(args[0].getString());
- out->endStringOp(state);
- } else {
+ out->beginStringOp(state);
+ doShowText(args[0].getString());
+ out->endStringOp(state);
+ if (!ocState) {
doIncCharCount(args[0].getString());
}
}
@@ -3782,11 +3752,10 @@ void Gfx::opMoveShowText(Object args[], int numArgs) {
ty = state->getLineY() - state->getLeading();
state->textMoveTo(tx, ty);
out->updateTextPos(state);
- if (ocState) {
- out->beginStringOp(state);
- doShowText(args[0].getString());
- out->endStringOp(state);
- } else {
+ out->beginStringOp(state);
+ doShowText(args[0].getString());
+ out->endStringOp(state);
+ if (!ocState) {
doIncCharCount(args[0].getString());
}
}
@@ -3810,11 +3779,10 @@ void Gfx::opMoveSetShowText(Object args[], int numArgs) {
out->updateWordSpace(state);
out->updateCharSpace(state);
out->updateTextPos(state);
+ out->beginStringOp(state);
+ doShowText(args[2].getString());
+ out->endStringOp(state);
if (ocState) {
- out->beginStringOp(state);
- doShowText(args[2].getString());
- out->endStringOp(state);
- } else {
doIncCharCount(args[2].getString());
}
}
@@ -3833,34 +3801,33 @@ void Gfx::opShowSpaceText(Object args[], int numArgs) {
out->updateFont(state);
fontChanged = gFalse;
}
- if (ocState) {
- out->beginStringOp(state);
- wMode = state->getFont()->getWMode();
- a = args[0].getArray();
- for (i = 0; i < a->getLength(); ++i) {
- a->get(i, &obj);
- if (obj.isNum()) {
+ out->beginStringOp(state);
+ wMode = state->getFont()->getWMode();
+ a = args[0].getArray();
+ for (i = 0; i < a->getLength(); ++i) {
+ a->get(i, &obj);
+ if (obj.isNum()) {
// this uses the absolute value of the font size to match
// Acrobat's behavior
- if (wMode) {
- state->textShift(0, -obj.getNum() * 0.001 *
- state->getFontSize());
- } else {
- state->textShift(-obj.getNum() * 0.001 *
- state->getFontSize() *
- state->getHorizScaling(), 0);
- }
- out->updateTextShift(state, obj.getNum());
- } else if (obj.isString()) {
- doShowText(obj.getString());
+ if (wMode) {
+ state->textShift(0, -obj.getNum() * 0.001 *
+ state->getFontSize());
} else {
- error(errSyntaxError, getPos(),
- "Element of show/space array must be number or string");
+ state->textShift(-obj.getNum() * 0.001 *
+ state->getFontSize() *
+ state->getHorizScaling(), 0);
}
- obj.free();
+ out->updateTextShift(state, obj.getNum());
+ } else if (obj.isString()) {
+ doShowText(obj.getString());
+ } else {
+ error(errSyntaxError, getPos(),
+ "Element of show/space array must be number or string");
}
- out->endStringOp(state);
- } else {
+ obj.free();
+ }
+ out->endStringOp(state);
+ if (!ocState) {
a = args[0].getArray();
for (i = 0; i < a->getLength(); ++i) {
a->get(i, &obj);
@@ -4018,7 +3985,8 @@ void Gfx::doShowText(GooString *s) {
originX *= state->getFontSize();
originY *= state->getFontSize();
state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
- out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
+ if (ocState)
+ out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
state->shift(tdx, tdy);
p += n;
@@ -4055,7 +4023,8 @@ void Gfx::doShowText(GooString *s) {
dy *= state->getFontSize();
}
state->textTransformDelta(dx, dy, &tdx, &tdy);
- out->drawString(state, s);
+ if (ocState)
+ out->drawString(state, s);
state->shift(tdx, tdy);
}
@@ -4063,7 +4032,7 @@ void Gfx::doShowText(GooString *s) {
out->endString(state);
}
- if (patternFill) {
+ if (patternFill && ocState) {
out->saveTextPos(state);
// tell the OutputDev to do the clipping
out->endTextObject(state);
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index ac4942d..ee22356 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -692,7 +692,7 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
//----- external font file for Base-14 font
if (!ps && !isCIDFont() && ((Gfx8BitFont *)this)->base14) {
base14Name = new GooString(((Gfx8BitFont *)this)->base14->base14Name);
- if ((path = globalParams->findFontFile(base14Name))) {
+ if ((path = globalParams->findBase14FontFile(base14Name, this))) {
if ((fontLoc = getExternalFont(path, gFalse))) {
delete base14Name;
return fontLoc;
diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 73a9855..e603795 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -208,22 +208,27 @@ public:
GooString *name;
GBool bold;
GBool italic;
+ GBool oblique;
+ GBool fixedWidth;
GooString *path;
SysFontType type;
int fontNum; // for TrueType collections
- SysFontInfo(GooString *nameA, GBool boldA, GBool italicA,
+ SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
GooString *pathA, SysFontType typeA, int fontNumA);
~SysFontInfo();
GBool match(SysFontInfo *fi);
+ GBool match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA);
GBool match(GooString *nameA, GBool boldA, GBool italicA);
};
-SysFontInfo::SysFontInfo(GooString *nameA, GBool boldA, GBool italicA,
+SysFontInfo::SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
GooString *pathA, SysFontType typeA, int fontNumA) {
name = nameA;
bold = boldA;
italic = italicA;
+ oblique = obliqueA;
+ fixedWidth = fixedWidthA;
path = pathA;
type = typeA;
fontNum = fontNumA;
@@ -236,7 +241,12 @@ SysFontInfo::~SysFontInfo() {
GBool SysFontInfo::match(SysFontInfo *fi) {
return !strcasecmp(name->getCString(), fi->name->getCString()) &&
- bold == fi->bold && italic == fi->italic;
+ bold == fi->bold && italic == fi->italic && oblique == fi->oblique && fixedWidth == fi->fixedWidth;
+}
+
+GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA) {
+ return !strcasecmp(name->getCString(), nameA->getCString()) &&
+ bold == boldA && italic == italicA && oblique == obliqueA && fixedWidth == fixedWidthA;
}
GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA) {
@@ -253,7 +263,7 @@ public:
SysFontList();
~SysFontList();
- SysFontInfo *find(GooString *name, GBool exact);
+ SysFontInfo *find(GooString *name, GBool isFixedWidth, GBool exact);
#ifdef WIN32
void scanWindowsFonts(GooString *winFontDir);
@@ -279,9 +289,9 @@ SysFontList::~SysFontList() {
deleteGooList(fonts, SysFontInfo);
}
-SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
+SysFontInfo *SysFontList::find(GooString *name, GBool fixedWidth, GBool exact) {
GooString *name2;
- GBool bold, italic;
+ GBool bold, italic, oblique;
SysFontInfo *fi;
char c;
int n, i;
@@ -321,6 +331,15 @@ SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
italic = gFalse;
}
+ // look for "Oblique"
+ if (n > 6 && !strcmp(name2->getCString() + n - 7, "Oblique")) {
+ name2->del(n - 7, 7);
+ oblique = gTrue;
+ n -= 6;
+ } else {
+ oblique = gFalse;
+ }
+
// look for "Bold"
if (n > 4 && !strcmp(name2->getCString() + n - 4, "Bold")) {
name2->del(n - 4, 4);
@@ -352,7 +371,7 @@ SysFontInfo *SysFontList::find(GooString *name, GBool exact) {
fi = NULL;
for (i = 0; i < fonts->getLength(); ++i) {
fi = (SysFontInfo *)fonts->get(i);
- if (fi->match(name2, bold, italic)) {
+ if (fi->match(name2, bold, italic, oblique, fixedWidth)) {
break;
}
fi = NULL;
@@ -624,9 +643,7 @@ GlobalParams::GlobalParams(const char *customPopplerDataDir)
unicodeMapCache = new UnicodeMapCache();
cMapCache = new CMapCache();
-#ifdef _WIN32
baseFontsInitialized = gFalse;
-#endif
#ifdef ENABLE_PLUGINS
plugins = new GooList();
securityHandlers = new GooList();
@@ -986,7 +1003,7 @@ static const char *getFontLang(GfxFont *font)
return lang;
}
-static FcPattern *buildFcPattern(GfxFont *font)
+static FcPattern *buildFcPattern(GfxFont *font, GooString *base14Name)
{
int weight = -1,
slant = -1,
@@ -998,7 +1015,7 @@ static FcPattern *buildFcPattern(GfxFont *font)
FcPattern *p;
// this is all heuristics will be overwritten if font had proper info
- name = font->getName()->getCString();
+ name = (base14Name == NULL) ? font->getName()->getCString() : base14Name->getCString();
modifiers = strchr (name, ',');
if (modifiers == NULL)
@@ -1114,8 +1131,8 @@ GooString *GlobalParams::findFontFile(GooString *fontName) {
FILE *f;
int i, j;
- lockGlobalParams;
setupBaseFonts(NULL);
+ lockGlobalParams;
if ((path = (GooString *)fontFiles->lookup(fontName))) {
path = path->copy();
unlockGlobalParams;
@@ -1153,9 +1170,16 @@ GooString *GlobalParams::findFontFile(GooString *fontName) {
void GlobalParams::setupBaseFonts(char *dir) {
}
+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
+ SysFontType type;
+ int fontNum;
+
+ return findSystemFontFile(font, &type, &fontNum, NULL, base14Name);
+}
+
GooString *GlobalParams::findSystemFontFile(GfxFont *font,
SysFontType *type,
- int *fontNum, GooString *substituteFontName) {
+ int *fontNum, GooString *substituteFontName, GooString *base14Name) {
SysFontInfo *fi = NULL;
FcPattern *p=0;
GooString *path = NULL;
@@ -1164,7 +1188,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
fontName = fontName->copy();
lockGlobalParams;
- if ((fi = sysFonts->find(fontName, gTrue))) {
+ if ((fi = sysFonts->find(fontName, font->isFixedWidth(), gTrue))) {
path = fi->path->copy();
*type = fi->type;
*fontNum = fi->fontNum;
@@ -1175,7 +1199,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
FcFontSet *set;
int i;
FcLangSet *lb = NULL;
- p = buildFcPattern(font);
+ p = buildFcPattern(font, base14Name);
if (!p)
goto fin;
@@ -1242,6 +1266,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
int weight, slant;
GBool bold = font->isBold();
GBool italic = font->isItalic();
+ GBool oblique = gFalse;
FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD
@@ -1251,10 +1276,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
}
if (slant == FC_SLANT_ITALIC)
italic = gTrue;
+ if (slant == FC_SLANT_OBLIQUE)
+ oblique = gTrue;
*fontNum = 0;
*type = (!strncasecmp(ext,".ttc",4)) ? sysFontTTC : sysFontTTF;
FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
- fi = new SysFontInfo(fontName->copy(), bold, italic,
+ fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
new GooString((char*)s), *type, *fontNum);
sysFonts->addFcFont(fi);
path = new GooString((char*)s);
@@ -1264,6 +1291,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
int weight, slant;
GBool bold = font->isBold();
GBool italic = font->isItalic();
+ GBool oblique = gFalse;
FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD
@@ -1273,10 +1301,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
}
if (slant == FC_SLANT_ITALIC)
italic = gTrue;
+ if (slant == FC_SLANT_OBLIQUE)
+ oblique = gTrue;
*fontNum = 0;
*type = (!strncasecmp(ext,".pfa",4)) ? sysFontPFA : sysFontPFB;
FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
- fi = new SysFontInfo(fontName->copy(), bold, italic,
+ fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
new GooString((char*)s), *type, *fontNum);
sysFonts->addFcFont(fi);
path = new GooString((char*)s);
@@ -1295,7 +1325,7 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
}
FcFontSetDestroy(set);
}
- if (path == NULL && (fi = sysFonts->find(fontName, gFalse))) {
+ if (path == NULL && (fi = sysFonts->find(fontName, font->isFixedWidth(), gFalse))) {
path = fi->path->copy();
*type = fi->type;
*fontNum = fi->fontNum;
@@ -1309,7 +1339,15 @@ fin:
#elif WITH_FONTCONFIGURATION_WIN32
#include "GlobalParamsWin.cc"
+
+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
+ return findFontFile(base14Name);
+}
#else
+GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
+ return findFontFile(base14Name);
+}
+
static struct {
const char *name;
const char *t1FileName;
@@ -1391,12 +1429,12 @@ GooString *GlobalParams::findSystemFontFile(GfxFont *font,
path = NULL;
lockGlobalParams;
- if ((fi = sysFonts->find(font->getName(), gFalse))) {
+ if ((fi = sysFonts->find(font->getName(), font->isFixedWidth(), gFalse))) {
path = fi->path->copy();
*type = fi->type;
*fontNum = fi->fontNum;
}
- unlockGlobalParams;
+ unlockGlobalParams;
return path;
}
#endif
diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
index be1d4b6..ac6b5aa 100644
--- a/poppler/GlobalParams.h
+++ b/poppler/GlobalParams.h
@@ -147,8 +147,10 @@ public:
FILE *findCMapFile(GooString *collection, GooString *cMapName);
FILE *findToUnicodeFile(GooString *name);
GooString *findFontFile(GooString *fontName);
+ GooString *findBase14FontFile(GooString *base14Name, GfxFont *font);
GooString *findSystemFontFile(GfxFont *font, SysFontType *type,
- int *fontNum, GooString *substituteFontName = NULL);
+ int *fontNum, GooString *substituteFontName = NULL,
+ GooString *base14Name = NULL);
GooString *findCCFontFile(GooString *collection);
GBool getPSExpandSmaller();
GBool getPSShrinkLarger();
@@ -288,8 +290,8 @@ private:
GooHash *cMapDirs; // list of CMap dirs, indexed by collection
// name [GooList[GooString]]
GooList *toUnicodeDirs; // list of ToUnicode CMap dirs [GooString]
-#ifdef _WIN32
GBool baseFontsInitialized;
+#ifdef _WIN32
GooHash *substFiles; // windows font substitutes (for CID fonts)
#endif
GooHash *fontFiles; // font files: font name mapped to path
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler