[gs-commits] rev 10877 - trunk/gs/psi
chrisl at ghostscript.com
chrisl at ghostscript.com
Mon Mar 8 09:28:49 UTC 2010
Author: chrisl
Date: 2010-03-08 09:28:49 +0000 (Mon, 08 Mar 2010)
New Revision: 10877
Modified:
trunk/gs/psi/fapi_ft.c
trunk/gs/psi/zfapi.c
Log:
Latest improvements to the FAPI/FT bridge code. This code resolves the issues with font matrices which do more than just scale. It is not yet "finished", but is too big a step forward to risk losing.
Modified: trunk/gs/psi/fapi_ft.c
===================================================================
--- trunk/gs/psi/fapi_ft.c 2010-03-05 21:01:34 UTC (rev 10876)
+++ trunk/gs/psi/fapi_ft.c 2010-03-08 09:28:49 UTC (rev 10877)
@@ -422,20 +422,51 @@
static void
transform_decompose(FT_Matrix *a_transform, FT_Fixed *a_x_scale, FT_Fixed *a_y_scale)
{
- float a = a_transform->xx / 65536.0;
- float b = a_transform->xy / 65536.0;
- float c = a_transform->yx / 65536.0;
- float d = a_transform->yy / 65536.0;
-
- float scale = sqrt(fabs(a * d - b * c));
-
- a_transform->xx = a / scale * 65536.0;
- a_transform->xy = b / scale * 65536.0;
- a_transform->yx = c / scale * 65536.0;
- a_transform->yy = d / scale * 65536.0;
-
- *a_x_scale = scale * 65536.0;
- *a_y_scale = scale * 65536.0;
+ double scalex, scaley, fact = 1.0;
+ FT_Matrix ftscale_mat;
+
+ scalex = hypot ((double)a_transform->xx, (double)a_transform->xy) / 65536.0;
+ scaley = hypot ((double)a_transform->yx, (double)a_transform->yy) / 65536.0;
+
+ /* FT clamps the width and height to a lower limit of 1.0 units
+ * (note: as FT stores it in 64ths of a unit, that is 64)
+ * So if either the width or the height are <1.0 here, we scale
+ * the width and height appropriately, and then compensate using
+ * the "final" matrix for FT
+ */
+ /* We use 1 1/64th to calculate the scale, so that we *guarantee* the
+ * scalex/y we calculate will be >64 after rounding.
+ */
+ if (scalex > scaley)
+ {
+ if (scaley < 1.0)
+ {
+ fact = 1.016 / scaley;
+ scaley = scaley * fact;
+ scalex = scalex * fact;
+ }
+ }
+ else
+ {
+ if (scalex < 1.0)
+ {
+ fact = 1.016 / scalex;
+ scalex = scalex * fact;
+ scaley = scaley * fact;
+ }
+ }
+
+ ftscale_mat.xx = ((1.0 / scalex)) * 65536.0;
+ ftscale_mat.xy = 0;
+ ftscale_mat.yx = 0;
+ ftscale_mat.yy = ((1.0 / scaley)) * 65536.0;
+
+ FT_Matrix_Multiply (a_transform, &ftscale_mat);
+ memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix));
+
+ /* Return values ready scaled for FT */
+ *a_x_scale = scalex * 64;
+ *a_y_scale = scaley * 64;
}
/*
@@ -580,10 +611,9 @@
*/
if (face)
{
- static const FT_Matrix ft_reflection = { 65536, 0, 0, -65536 };
FT_Matrix ft_transform;
FT_F26Dot6 width, height;
-
+
/* Convert the GS transform into an FT transform.
* Ignore the translation elements because they contain very large values
* derived from the current transformation matrix and so are of no use.
@@ -597,10 +627,7 @@
* transform.
*/
transform_decompose(&ft_transform, &width, &height);
-
- /* Convert width and height to 64ths of pixels and set the FreeType sizes. */
- width >>= 10;
- height >>= 10;
+
ft_error = FT_Set_Char_Size(face->ft_face, width, height,
a_font_scale->HWResolution[0] >> 16,
a_font_scale->HWResolution[1] >> 16);
Modified: trunk/gs/psi/zfapi.c
===================================================================
--- trunk/gs/psi/zfapi.c 2010-03-05 21:01:34 UTC (rev 10876)
+++ trunk/gs/psi/zfapi.c 2010-03-08 09:28:49 UTC (rev 10877)
@@ -577,7 +577,9 @@
switch((int)var_id) {
case FAPI_FONT_FEATURE_FontMatrix:
+#if 0
{ double FontMatrix_div = (ff->is_cid && !IsCIDFont(pbfont) ? 1000 : 1);
+
switch(index) {
case 0 : return pbfont->base->FontMatrix.xx / FontMatrix_div;
case 1 : return pbfont->base->FontMatrix.xy / FontMatrix_div;
@@ -587,6 +589,19 @@
case 5 : return pbfont->base->FontMatrix.ty / FontMatrix_div;
}
}
+#else
+ /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
+ {
+ switch(index) {
+ case 0 : return 1.0;
+ case 1 : return 0.0;
+ case 2 : return 0.0;
+ case 3 : return 1.0;
+ case 4 : return 0.0;
+ case 5 : return 0.0;
+ }
+ }
+#endif
case FAPI_FONT_FEATURE_WeightVector:
{ ref *Array, value;
@@ -1364,10 +1379,16 @@
static void compute_em_scale(const gs_font_base *pbfont, FAPI_metrics *metrics, double FontMatrix_div, double *em_scale_x, double *em_scale_y)
{ /* optimize : move this stuff to FAPI_refine_font */
+ gs_matrix mat;
gs_matrix *m = &pbfont->base->orig_FontMatrix;
int rounding_x, rounding_y; /* Striking out the 'float' representation error in FontMatrix. */
double sx, sy;
-
+
+ /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
+ m = &mat;
+ memset(m, 0x00, sizeof(gs_matrix));
+ m->xx = m->yy = 1.0;
+
if (m->xx == 0 && m->xy == 0 && m->yx == 0 && m->yy == 0)
m = &pbfont->base->FontMatrix;
sx = hypot(m->xx, m->xy) * metrics->em_x / FontMatrix_div;
@@ -1478,12 +1499,18 @@
int dx = arith_rshift_slow((pgs->ctm.tx_fixed >> shift_rd) + rast_orig_x + rounding, frac_pixel_shift);
int dy = arith_rshift_slow((pgs->ctm.ty_fixed >> shift_rd) + rast_orig_y + rounding, frac_pixel_shift);
- if (dx + rast.left_indent < 0 || dx + rast.left_indent + rast.black_width > dev1->width)
+ if (dx + rast.left_indent < 0 || dx + rast.left_indent + rast.black_width > dev1->width) {
eprintf2("Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
dx + rast.left_indent, dx + rast.left_indent + rast.black_width - dev1->width);
- if (dy + rast.top_indent < 0 || dy + rast.top_indent + rast.black_height > dev1->height)
+ if (dx + rast.left_indent < 0)
+ dx -= dx + rast.left_indent;
+ }
+ if (dy + rast.top_indent < 0 || dy + rast.top_indent + rast.black_height > dev1->height) {
eprintf2("Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n",
dy + rast.top_indent, dy + rast.top_indent + rast.black_height - dev1->height);
+ if (dy + rast.top_indent < 0)
+ dy -= dy + rast.top_indent;
+ }
if ((code = fapi_copy_mono(dev1, &rast, dx, dy)) < 0)
return code;
@@ -1614,7 +1641,7 @@
I->face.HWResolution[1] != dev->HWResolution[1]
) {
FAPI_font_scale font_scale = {{1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true};
- gs_matrix *base_font_matrix = &I->initial_FontMatrix;
+ gs_matrix imat, scale_mat, scale_ctm, *base_font_matrix;
double dx, dy;
I->face.font_id = pbfont->id;
@@ -1628,6 +1655,32 @@
font_scale.subpixels[1] = 1 << log2_scale.y;
font_scale.align_to_pixels = align_to_pixels;
+#if 1
+ /* We apply the entire transform to the glyph (that is ctm x FontMatrix)
+ * at render time.
+ */
+
+ memset(&scale_ctm, 0x00, sizeof(gs_matrix));
+ scale_ctm.xx = dev->HWResolution[0]/72;
+ scale_ctm.yy = dev->HWResolution[1]/72;
+
+ code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
+
+ code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling */
+
+ font_scale.matrix[0] = (FracInt)(scale_mat.xx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[1] = -(FracInt)(scale_mat.xy * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[2] = (FracInt)(scale_mat.yx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[3] = -(FracInt)(scale_mat.yy * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[4] = (FracInt)(scale_mat.tx * FontMatrix_div * scale + 0.5);
+ font_scale.matrix[5] = (FracInt)(scale_mat.ty * FontMatrix_div * scale + 0.5);
+#else
+
+# if 1
+ base_font_matrix = &I->initial_FontMatrix;
+# else
+ base_font_matrix = &pbfont->base->orig_FontMatrix;
+# endif
if (base_font_matrix->xx == 0 && base_font_matrix->xy == 0 &&
base_font_matrix->yx == 0 && base_font_matrix->yy == 0)
base_font_matrix = &pbfont->base->FontMatrix;
@@ -1643,13 +1696,14 @@
for X and Y. It is not clear what to do when base_font_matrix is anisotropic
(i.e. dx != dy), but we did not meet such fonts before now.
*/
- font_scale.matrix[0] = (FracInt)(ctm->xx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
- font_scale.matrix[1] = -(FracInt)(ctm->xy * FontMatrix_div / dy * 72 / dev->HWResolution[0] * scale + 0.5);
+ font_scale.matrix[0] = (FracInt)(ctm->xx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
+ font_scale.matrix[1] = -(FracInt)(ctm->xy * FontMatrix_div / dy * 72 / dev->HWResolution[0] * scale + 0.5);
font_scale.matrix[2] = (FracInt)(ctm->yx * FontMatrix_div / dx * 72 / dev->HWResolution[1] * scale + 0.5);
font_scale.matrix[3] = -(FracInt)(ctm->yy * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
font_scale.matrix[4] = (FracInt)(ctm->tx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
font_scale.matrix[5] = (FracInt)(ctm->ty * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
- /* Note: the ctm mapping here is upside down. */
+#endif
+ /* Note: the ctm mapping here is upside down. */
font_scale.HWResolution[0] = (FracInt)((double)dev->HWResolution[0] * font_scale.subpixels[0] * scale);
font_scale.HWResolution[1] = (FracInt)((double)dev->HWResolution[1] * font_scale.subpixels[1] * scale);
More information about the gs-commits
mailing list