~ubuntu-branches/ubuntu/hardy/ghostscript/hardy

« back to all changes in this revision

Viewing changes to src/gdevpdtt.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2007-11-22 12:17:43 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071122121743-cd70s3ypq0r243mp
Tags: 8.61.dfsg.1-0ubtuntu1
* New upstream release
  o Final 8.61 release
* debian/patches/09_ijs_krgb_support.dpatch: Adapted to upstream changes.
* debian/rules: Updated CUPS-related variables for "make install" calls.
* debian/rules: Remove /usr/include/ghostscript from the ghostscript
  package, they go into lings-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: gdevpdtt.c 8022 2007-06-05 22:23:38Z giles $ */
 
14
/* $Id: gdevpdtt.c 8360 2007-11-13 10:01:55Z ken $ */
15
15
/* Text processing for pdfwrite. */
16
16
#include "math_.h"
17
17
#include "string_.h"
40
40
#include "gdevpdtt.h"
41
41
#include "gdevpdti.h"
42
42
#include "gxhldevc.h"
 
43
#include "gzpath.h"
43
44
 
44
45
/* ================ Text enumerator ================ */
45
46
 
53
54
static gs_glyph standard_glyph_code_for_notdef = GS_NO_GLYPH;
54
55
 
55
56
/* Define the auxiliary procedures for text processing. */
56
 
private int
 
57
static int
57
58
pdf_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
58
59
{
59
60
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
70
71
    gs_text_enum_copy_dynamic(pte, pfrom, false);
71
72
    return 0;
72
73
}
73
 
private bool
 
74
static bool
74
75
pdf_text_is_width_only(const gs_text_enum_t *pte)
75
76
{
76
77
    const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
79
80
        return gs_text_is_width_only(penum->pte_default);
80
81
    return false;
81
82
}
82
 
private int
 
83
static int
83
84
pdf_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
84
85
{
85
86
    const pdf_text_enum_t *const penum = (const pdf_text_enum_t *)pte;
88
89
        return gs_text_current_width(penum->pte_default, pwidth);
89
90
    return_error(gs_error_rangecheck); /* can't happen */
90
91
}
91
 
private int
 
92
static int
92
93
pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
93
94
                   gs_text_cache_control_t control)
94
95
{
216
217
    }
217
218
    return_error(gs_error_unregistered); /* can't happen */
218
219
}
219
 
private int
 
220
static int
220
221
pdf_text_retry(gs_text_enum_t *pte)
221
222
{
222
223
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
225
226
        return gs_text_retry(penum->pte_default);
226
227
    return_error(gs_error_rangecheck); /* can't happen */
227
228
}
228
 
private void
 
229
static void
229
230
pdf_text_release(gs_text_enum_t *pte, client_name_t cname)
230
231
{
231
232
    pdf_text_enum_t *const penum = (pdf_text_enum_t *)pte;
247
248
}
248
249
 
249
250
/* Begin processing text. */
250
 
private text_enum_proc_process(pdf_text_process);
251
 
private const gs_text_enum_procs_t pdf_text_procs = {
 
251
static text_enum_proc_process(pdf_text_process);
 
252
static const gs_text_enum_procs_t pdf_text_procs = {
252
253
    pdf_text_resync, pdf_text_process,
253
254
    pdf_text_is_width_only, pdf_text_current_width,
254
255
    pdf_text_set_cache, pdf_text_retry,
255
256
    pdf_text_release
256
257
};
257
258
 
258
 
private int
 
259
static int
259
260
pdf_prepare_text_drawing(gx_device_pdf *const pdev, gs_text_enum_t *pte)
260
261
{
261
262
    gs_imager_state * pis = pte->pis;
336
337
        pdf_current_page(pdev)->text_rotation.counts[i] += text->size;
337
338
    }
338
339
 
 
340
    pdev->last_charpath_op = 0;
 
341
    if ((text->operation & TEXT_DO_ANY_CHARPATH) && !path0->first_subpath) {
 
342
        if(pdf_compare_text_state_for_charpath(pdev->text->text_state, pdev, pis, font, text))
 
343
            pdev->last_charpath_op = text->operation & TEXT_DO_ANY_CHARPATH;
 
344
    }
 
345
 
339
346
    if (font->FontType == ft_user_defined &&
340
347
        (text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH)) {
341
348
        /* This is stringwidth, see gx_default_text_begin.
400
407
/*
401
408
 * Compute id for a font cache element.
402
409
 */
403
 
private ulong 
 
410
static ulong 
404
411
pdf_font_cache_elem_id(gs_font *font)
405
412
{
406
413
#if 0
440
447
    return 0;
441
448
}
442
449
 
443
 
private void
 
450
static void
444
451
pdf_remove_font_cache_elem(pdf_font_cache_elem_t *e0)
445
452
{
446
453
    gx_device_pdf *pdev = e0->pdev;
471
478
        }
472
479
}
473
480
 
474
 
private void
 
481
static void
475
482
font_cache_elem_array_sizes(gx_device_pdf *pdev, gs_font *font,
476
483
                            int *num_widths, int *num_chars) 
477
484
{
499
506
    }
500
507
}
501
508
 
502
 
private int 
 
509
static int 
503
510
alloc_font_cache_elem_arrays(gx_device_pdf *pdev, pdf_font_cache_elem_t *e,
504
511
                             gs_font *font)
505
512
{
567
574
    return 0;
568
575
}
569
576
 
570
 
private int 
 
577
static int 
571
578
pdf_notify_remove_font(void *proc_data, void *event_data)
572
579
{   /* gs_font_finalize passes event_data == NULL, so check it here. */
573
580
    if (event_data == NULL)
700
707
    }
701
708
}
702
709
 
703
 
int
704
 
font_orig_scale(const gs_font *font, double *sx)
705
 
{   
706
 
    gs_matrix mat;
707
 
    int code = pdf_font_orig_matrix(font, &mat);
708
 
 
709
 
    if (code < 0)
710
 
        return code;
711
 
    *sx = mat.xx;
712
 
    return 0;
713
 
}
714
 
 
715
710
/* 
716
711
 * Check the Encoding compatibility 
717
712
 */
736
731
/* 
737
732
 * Check ������� the Encoding has listed glyphs.
738
733
 */
739
 
private bool
 
734
static bool
740
735
pdf_check_encoding_has_glyphs(const pdf_font_resource_t *pdfont, 
741
736
            const pdf_char_glyph_pair_t *pairs, int num_chars)
742
737
{
761
756
/*
762
757
 * Check font resource for encoding compatibility.
763
758
 */
764
 
private bool
 
759
static bool
765
760
pdf_is_compatible_encoding(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
766
761
                           gs_font *font, const pdf_char_glyph_pair_t *pairs, int num_chars)
767
762
{   
817
812
/*
818
813
 * Check whethet the font resource has glyphs.
819
814
 */
820
 
private bool
 
815
static bool
821
816
pdf_font_has_glyphs(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
822
817
                           gs_font *font, const pdf_char_glyph_pair_t *pairs, int num_chars)
823
818
{   
847
842
/* 
848
843
 * Find a font resource compatible with a given font. 
849
844
 */
850
 
private int
 
845
static int
851
846
pdf_find_font_resource(gx_device_pdf *pdev, gs_font *font,
852
847
                       pdf_resource_type_t type,
853
848
                       pdf_font_resource_t **ppdfont,
900
895
/* 
901
896
 * Find a type0 font resource for a gived descendent name and CMap name. 
902
897
 */
903
 
private int
 
898
static int
904
899
pdf_find_type0_font_resource(gx_device_pdf *pdev, const pdf_font_resource_t *pdsubf, 
905
 
            const gs_const_string *CMapName, pdf_font_resource_t **ppdfont)
 
900
            const gs_const_string *CMapName, uint font_index, pdf_font_resource_t **ppdfont)
906
901
{
907
902
    pdf_resource_t **pchain = pdev->resources[resourceFont].chains;
908
903
    pdf_resource_t *pres;
916
911
                continue;
917
912
            if (pdfont->u.type0.DescendantFont != pdsubf)
918
913
                continue;
 
914
            if (pdfont->u.type0.font_index != font_index)
 
915
                continue;
919
916
            if (pdfont->BaseFont.size != pdsubf->BaseFont.size + CMapName->size + 1)
920
917
                continue;
921
918
            if (memcmp(pdfont->BaseFont.data + pdsubf->BaseFont.size + 1, 
929
926
}
930
927
 
931
928
 
932
 
private int pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
 
929
static int pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
933
930
                       pdf_font_resource_t **ppdfont, 
934
931
                       pdf_char_glyph_pairs_t *cgp);
935
932
 
971
968
/*
972
969
 * Refine index of BaseEncoding.
973
970
 */
974
 
private int 
 
971
static int 
975
972
pdf_refine_encoding_index(const gx_device_pdf *pdev, int index, bool is_standard)
976
973
{
977
974
    if (pdev->ForOPDFRead) {
1032
1029
                        bfont->nearest_encoding_index, true);
1033
1030
    pdfont->u.simple.s.type3.char_procs = NULL;
1034
1031
    pdfont->u.simple.s.type3.cached = cached;
1035
 
    pdfont->u.simple.s.type3.FontBBox.p.x = (int)floor(bfont->FontBBox.p.x);
1036
 
    pdfont->u.simple.s.type3.FontBBox.p.y = (int)floor(bfont->FontBBox.p.y);
1037
 
    pdfont->u.simple.s.type3.FontBBox.q.x = (int)ceil(bfont->FontBBox.q.x);
1038
 
    pdfont->u.simple.s.type3.FontBBox.q.y = (int)ceil(bfont->FontBBox.q.y);
 
1032
    pdfont->u.simple.s.type3.FontBBox.p.x = bfont->FontBBox.p.x;
 
1033
    pdfont->u.simple.s.type3.FontBBox.p.y = bfont->FontBBox.p.y;
 
1034
    pdfont->u.simple.s.type3.FontBBox.q.x = bfont->FontBBox.q.x;
 
1035
    pdfont->u.simple.s.type3.FontBBox.q.y = bfont->FontBBox.q.y;
1039
1036
    pdfont->u.simple.s.type3.FontMatrix = bfont->FontMatrix;
1040
1037
    pdfont->u.simple.s.type3.Resources = cos_dict_alloc(pdev, "pdf_make_font3_resource");
1041
1038
    if (pdfont->u.simple.s.type3.Resources == NULL)
1060
1057
 * This procedure is only intended to be called
1061
1058
 * from a few places in the text code.
1062
1059
 */
1063
 
private int
 
1060
static int
1064
1061
pdf_make_font_resource(gx_device_pdf *pdev, gs_font *font,
1065
1062
                       pdf_font_resource_t **ppdfont, 
1066
1063
                       pdf_char_glyph_pairs_t *cgp)
1231
1228
    return 1;
1232
1229
}
1233
1230
 
1234
 
/* Get a synthesized Type 3 font scale. */
1235
 
void 
1236
 
pdf_font3_scale(gx_device_pdf *pdev, gs_font *font, double *scale)
1237
 
{
1238
 
    pdf_font_resource_t *pdfont;
1239
 
 
1240
 
    pdf_attached_font_resource(pdev, font, &pdfont, NULL, NULL, NULL, NULL);
1241
 
    *scale = pdfont->u.simple.s.type3.FontMatrix.xx;
1242
 
}
1243
 
 
1244
1231
/*
1245
1232
 * Check for simple font.
1246
1233
 */
1266
1253
/*
1267
1254
 * Enumerate glyphs for a text.
1268
1255
 */
1269
 
private int
 
1256
static int
1270
1257
pdf_next_char_glyph(gs_text_enum_t *penum, const gs_string *pstr, 
1271
1258
               /* const */ gs_font *font, bool font_is_simple, 
1272
1259
               gs_char *char_code, gs_char *cid, gs_glyph *glyph)
1290
1277
    return 0;
1291
1278
}
1292
1279
 
1293
 
private void
 
1280
static void
1294
1281
store_glyphs(pdf_char_glyph_pairs_t *cgp, 
1295
1282
             byte *glyph_usage, int char_cache_size,
1296
1283
             gs_char char_code, gs_char cid, gs_glyph glyph)
1319
1306
     */
1320
1307
}
1321
1308
 
1322
 
private gs_char
 
1309
static gs_char
1323
1310
pdf_new_char_code_in_pdfont(pdf_char_glyph_pairs_t *cgp, gs_glyph glyph, int *last_reserved_char)
1324
1311
{   /* Returns 256 if encoding overflows. */
1325
1312
    int j, ch;
1339
1326
    return ch;
1340
1327
}
1341
1328
 
1342
 
private gs_char
 
1329
static gs_char
1343
1330
pdf_reserve_char_code_in_pdfont(pdf_font_resource_t *pdfont, pdf_char_glyph_pairs_t *cgp, gs_glyph glyph, 
1344
1331
                                int *last_reserved_char)
1345
1332
{   /* Returns 256 if encoding overflows. */
1368
1355
        if (standard_glyph_code_for_notdef == GS_NO_GLYPH)
1369
1356
            standard_glyph_code_for_notdef = 
1370
1357
                    gs_c_name_glyph((const byte *)".notdef", 7) - gs_c_min_std_encoding_glyph;
1371
 
        for (ch = 0; ch < 256; ch++) {
 
1358
        for (ch = *last_reserved_char + 1; ch < 256; ch++) {
1372
1359
            pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
1373
1360
 
1374
1361
            if (pet->glyph == GS_NO_GLYPH && enc[ch] == standard_glyph_code_for_notdef) {
 
1362
                *last_reserved_char = ch;
1375
1363
                break;
1376
1364
            }
1377
1365
        }
1398
1386
 
1399
1387
 
1400
1388
/* Allocate storage for the glyph set of the text. */
1401
 
private int
 
1389
static int
1402
1390
pdf_alloc_text_glyphs_table(gx_device_pdf *pdev, pdf_text_enum_t *penum, const gs_string *pstr)
1403
1391
{
1404
1392
    const int go = (pstr != NULL ? pstr->size : penum->text.size);
1416
1404
}
1417
1405
 
1418
1406
/* Build the glyph set of the text. */
1419
 
private int
 
1407
static int
1420
1408
pdf_make_text_glyphs_table(pdf_text_enum_t *penum, const gs_string *pstr, 
1421
1409
                byte *glyph_usage, int char_cache_size)
1422
1410
{
1458
1446
}
1459
1447
 
1460
1448
/* Build the glyph set of the glyphshow text, and re_encode the text. */
1461
 
private int
 
1449
static int
1462
1450
pdf_make_text_glyphs_table_unencoded(gx_device_pdf *pdev, pdf_char_glyph_pairs_t *cgp,
1463
1451
                gs_font *font, const gs_string *pstr, const gs_glyph *gdata,
1464
1452
                int *ps_encoding_index) 
1492
1480
    }
1493
1481
do_unknown:
1494
1482
    if (unknown) {
 
1483
        int last_reserved_char = -1;
1495
1484
         /* Using global glyph names. */
1496
1485
 
1497
1486
        /* Try to find an existing font resource, which has necessary glyphs. 
1515
1504
        /* Try to add glyphs to the current font resource. . */
1516
1505
        cgp->num_unused_chars = 0;
1517
1506
        cgp->num_all_chars = 0;
 
1507
 
 
1508
        if(pdfont != NULL)
 
1509
                last_reserved_char = pdfont->u.simple.last_reserved_char;
 
1510
 
1518
1511
        for (i = 0; i < pstr->size; i++) {
 
1512
                
1519
1513
            if (pdfont == NULL)
1520
1514
                ch = 256; /* Force new encoding. */
1521
1515
            else
1522
 
                ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &pdfont->u.simple.last_reserved_char);
 
1516
                ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &last_reserved_char);
1523
1517
            if (ch > 255) {
 
1518
                if(pdfont != NULL)
 
1519
                        last_reserved_char = pdfont->u.simple.last_reserved_char;
1524
1520
                /* Start a new font/encoding. */
1525
 
                int last_reserved_char = -1;
 
1521
                last_reserved_char = -1;
1526
1522
 
1527
1523
                cgp->num_unused_chars = 0;
1528
1524
                cgp->num_all_chars = 0;
1535
1531
                        return_error(gs_error_unregistered);
1536
1532
                    }
1537
1533
                }
1538
 
                if (pdfont != NULL)
1539
 
                    pdfont->u.simple.last_reserved_char = last_reserved_char;
1540
 
            }
1541
1534
        }
 
1535
    }
 
1536
        if (pdfont != NULL)
 
1537
            pdfont->u.simple.last_reserved_char = last_reserved_char;
1542
1538
        /* Change glyphs to char codes in the text : */
1543
1539
        for (i = 0; i < pstr->size; i++) {
1544
1540
            /* A trick : pdf_reserve_char_code_in_pdfont here simply encodes with cgp. */
1589
1585
 
1590
1586
 
1591
1587
/* Get/make font resource for the font with a known encoding. */
1592
 
private int
 
1588
static int
1593
1589
pdf_obtain_font_resource_encoded(gx_device_pdf *pdev, gs_font *font,
1594
1590
        pdf_font_resource_t **ppdfont, pdf_char_glyph_pairs_t *cgp)
1595
1591
{
1667
1663
}
1668
1664
 
1669
1665
/* Mark glyphs used in the text with the font resource. */
1670
 
private int
 
1666
static int
1671
1667
pdf_mark_text_glyphs(const gs_text_enum_t *penum, const gs_string *pstr,
1672
1668
            byte *glyph_usage, int char_cache_size)
1673
1669
{
1704
1700
}
1705
1701
 
1706
1702
/* Mark glyphs used in the glyphshow text with the font resource. */
1707
 
private int
 
1703
static int
1708
1704
pdf_mark_text_glyphs_unencoded(const gs_text_enum_t *penum, const gs_string *pstr,
1709
1705
            byte *glyph_usage, int char_cache_size)
1710
1706
{
1807
1803
                    pstr, glyph_usage, char_cache_size);
1808
1804
}
1809
1805
 
1810
 
private inline bool
 
1806
static inline bool
1811
1807
strings_equal(const gs_const_string *s1, const gs_const_string *s2)
1812
1808
{
1813
1809
    return s1->size == s2->size &&
1819
1815
 */
1820
1816
int
1821
1817
pdf_obtain_parent_type0_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdsubf, 
1822
 
                const gs_const_string *CMapName, pdf_font_resource_t **pdfont)
 
1818
                uint font_index, const gs_const_string *CMapName, pdf_font_resource_t **pdfont)
1823
1819
{
1824
 
    if (pdsubf->u.cidfont.parent != 0 && 
 
1820
    if (pdsubf->u.cidfont.parent != 0 &&
 
1821
            font_index == pdsubf->u.cidfont.parent->u.type0.font_index &&
1825
1822
            strings_equal(CMapName, &pdsubf->u.cidfont.parent->u.type0.CMapName))
1826
1823
        *pdfont = pdsubf->u.cidfont.parent;
1827
1824
    else {
1836
1833
         */
1837
1834
 
1838
1835
        if (pdsubf->u.cidfont.parent == NULL || 
1839
 
                pdf_find_type0_font_resource(pdev, pdsubf, CMapName, pdfont) <= 0) {
 
1836
                pdf_find_type0_font_resource(pdev, pdsubf, CMapName, font_index, pdfont) <= 0) {
1840
1837
            int code = pdf_font_type0_alloc(pdev, pdfont, gs_no_id, pdsubf, CMapName);
1841
1838
 
1842
1839
            if (code < 0)
1843
1840
                return code;
 
1841
            (*pdfont)->u.type0.font_index = font_index;
1844
1842
        }
1845
1843
        pdsubf->u.cidfont.parent = *pdfont;
1846
1844
    }
1880
1878
 * TEXT_ADD_TO_SPACE_WIDTH.  Note that this procedure fills in all the
1881
1879
 * values in ppts->values, not just the ones that need to be set now.
1882
1880
 */
1883
 
private int
 
1881
static int
1884
1882
transform_delta_inverse(const gs_point *pdelta, const gs_matrix *pmat,
1885
1883
                        gs_point *ppt)
1886
1884
{
1901
1899
    }
1902
1900
    return 0;
1903
1901
}
1904
 
int
1905
 
pdf_update_text_state(pdf_text_process_state_t *ppts,
1906
 
                      const pdf_text_enum_t *penum,
1907
 
                      pdf_font_resource_t *pdfont, const gs_matrix *pfmat)
 
1902
 
 
1903
float pdf_calculate_text_size(gs_imager_state *pis, pdf_font_resource_t *pdfont, 
 
1904
                              const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
 
1905
                              gs_font *font, gx_device_pdf *pdev)
1908
1906
{
1909
 
    gx_device_pdf *const pdev = (gx_device_pdf *)penum->dev;
1910
 
    gs_font *font = penum->current_font;
1911
 
    gs_fixed_point cpt;
1912
 
    gs_matrix orig_matrix, smat, tmat;
 
1907
    gs_matrix orig_matrix;
1913
1908
    double
1914
1909
        sx = pdev->HWResolution[0] / 72.0,
1915
1910
        sy = pdev->HWResolution[1] / 72.0;
1916
1911
    float size;
1917
 
    float c_s = 0, w_s = 0;
1918
 
    int mask = 0;
1919
 
    int code = gx_path_current_point(penum->path, &cpt);
1920
1912
 
1921
 
    if (code < 0)
1922
 
        return code;
1923
1913
 
1924
1914
    /* Get the original matrix of the base font. */
1925
1915
 
1946
1936
 
1947
1937
    /* Compute the scaling matrix and combined matrix. */
1948
1938
 
1949
 
    gs_matrix_invert(&orig_matrix, &smat);
1950
 
    gs_matrix_multiply(&smat, pfmat, &smat);
1951
 
    tmat = ctm_only(penum->pis);
1952
 
    tmat.tx = tmat.ty = 0;
1953
 
    gs_matrix_multiply(&smat, &tmat, &tmat);
 
1939
    gs_matrix_invert(&orig_matrix, smat);
 
1940
    gs_matrix_multiply(smat, pfmat, smat);
 
1941
    *tmat = ctm_only(pis);
 
1942
    tmat->tx = tmat->ty = 0;
 
1943
    gs_matrix_multiply(smat, tmat, tmat);
1954
1944
 
1955
1945
    /* Try to find a reasonable size value.  This isn't necessary, */
1956
1946
    /* but it's worth a little effort. */
1957
1947
 
1958
 
    size = hypot(tmat.yx, tmat.yy) / sy;
 
1948
    size = hypot(tmat->yx, tmat->yy) / sy;
1959
1949
    if (size < 0.01)
1960
 
        size = hypot(tmat.xx, tmat.xy) / sx;
 
1950
        size = hypot(tmat->xx, tmat->xy) / sx;
1961
1951
    if (size < 0.01)
1962
1952
        size = 1;
1963
1953
 
 
1954
    return(size);
 
1955
}
 
1956
 
 
1957
int
 
1958
pdf_update_text_state(pdf_text_process_state_t *ppts,
 
1959
                      const pdf_text_enum_t *penum,
 
1960
                      pdf_font_resource_t *pdfont, const gs_matrix *pfmat)
 
1961
{
 
1962
    gx_device_pdf *const pdev = (gx_device_pdf *)penum->dev;
 
1963
    gs_font *font = penum->current_font;
 
1964
    gs_fixed_point cpt;
 
1965
    gs_matrix smat, tmat;
 
1966
    float size;
 
1967
    float c_s = 0, w_s = 0;
 
1968
    int mask = 0;
 
1969
    int code = gx_path_current_point(penum->path, &cpt);
 
1970
 
 
1971
    if (code < 0)
 
1972
        return code;
 
1973
 
 
1974
 
 
1975
    size = pdf_calculate_text_size(penum->pis, pdfont, pfmat, &smat, &tmat, penum->current_font, pdev);
1964
1976
    /* Check for spacing parameters we can handle, and transform them. */
1965
1977
 
1966
1978
    if (penum->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
2014
2026
 * General graphics state commands are written now; text state commands
2015
2027
 * are written later.
2016
2028
 */
2017
 
private double
 
2029
static double
2018
2030
font_matrix_scaling(const gs_font *font)
2019
2031
{
2020
2032
    return fabs((font->FontMatrix.yy != 0 ? font->FontMatrix.yy :
2068
2080
    return pdf_set_text_state_values(pdev, &ppts->values);
2069
2081
}
2070
2082
 
2071
 
private int
2072
 
store_glyph_width(pdf_glyph_width_t *pwidth, int wmode, double scale,
 
2083
static int
 
2084
store_glyph_width(pdf_glyph_width_t *pwidth, int wmode, const gs_matrix *scale,
2073
2085
                  const gs_glyph_info_t *pinfo)
2074
2086
{
2075
2087
    double w, v;
2076
2088
 
2077
 
    pwidth->xy.x = pinfo->width[wmode].x * scale;
2078
 
    pwidth->xy.y = pinfo->width[wmode].y * scale;
 
2089
    gs_distance_transform(pinfo->width[wmode].x, pinfo->width[wmode].y, scale, &pwidth->xy);
2079
2090
    if (wmode)
2080
2091
        w = pwidth->xy.y, v = pwidth->xy.x;
2081
2092
    else
2083
2094
    if (v != 0)
2084
2095
        return 1;
2085
2096
    pwidth->w = w;
2086
 
    pwidth->v.x = pinfo->v.x * scale;
2087
 
    pwidth->v.y = pinfo->v.y * scale;
 
2097
    gs_distance_transform(pinfo->v.x, pinfo->v.y, scale, &pwidth->v);
2088
2098
    return 0;
2089
2099
}
2090
2100
 
2091
 
private int
2092
 
get_missing_width(gs_font_base *cfont, int wmode, double scale_c, 
 
2101
static int
 
2102
get_missing_width(gs_font_base *cfont, int wmode, const gs_matrix *scale_c,
2093
2103
                    pdf_glyph_widths_t *pwidths)
2094
2104
{
2095
2105
    gs_font_info_t finfo;
2100
2110
    if (code < 0)
2101
2111
        return code;
2102
2112
    if (wmode) {
2103
 
        pwidths->Width.xy.x = pwidths->real_width.xy.x = 0;
2104
 
        pwidths->Width.xy.y = pwidths->real_width.xy.y =
2105
 
                - finfo.MissingWidth * scale_c;
 
2113
        gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
 
2114
        pwidths->Width.xy.x = 0;
 
2115
        pwidths->Width.xy.y = pwidths->real_width.xy.y;
2106
2116
        pwidths->Width.w = pwidths->real_width.w =
2107
2117
                pwidths->Width.xy.y;
2108
2118
        pwidths->Width.v.x = - pwidths->Width.xy.y / 2;
2109
2119
        pwidths->Width.v.y = - pwidths->Width.xy.y;
2110
2120
    } else {
2111
 
        pwidths->Width.xy.x = pwidths->real_width.xy.x =
2112
 
                finfo.MissingWidth * scale_c;
 
2121
        gs_distance_transform(finfo.MissingWidth, 0.0, scale_c, &pwidths->real_width.xy);
 
2122
        pwidths->Width.xy.x = pwidths->real_width.xy.x;
 
2123
        pwidths->Width.xy.y = 0;
2113
2124
        pwidths->Width.w = pwidths->real_width.w =
2114
2125
                pwidths->Width.xy.x;
2115
 
        pwidths->Width.xy.y = pwidths->real_width.xy.y = 0;
2116
2126
        pwidths->Width.v.x = pwidths->Width.v.y = 0;
2117
2127
    }
2118
2128
    /*
2138
2148
    gs_font_base *cfont = pdf_font_resource_font(pdfont, false);
2139
2149
    gs_font *ofont = orig_font;
2140
2150
    gs_glyph_info_t info;
2141
 
    /*
2142
 
     * orig_scale is 1.0 for TrueType, 0.001 or 1.0/2048 for Type 1.
2143
 
     */
2144
 
    double sxc, sxo;
2145
 
    double scale_c, scale_o;
 
2151
    gs_matrix scale_c, scale_o;
2146
2152
    int code, rcode = 0;
2147
2153
    gs_point v;
2148
2154
    int allow_cdevproc_callout = (orig_font->FontType == ft_CID_TrueType 
2151
2157
 
2152
2158
    if (ofont->FontType == ft_composite)
2153
2159
        return_error(gs_error_unregistered); /* Must not happen. */
2154
 
    code = font_orig_scale((const gs_font *)cfont, &sxc);
2155
 
    if (code < 0)
2156
 
        return code;
2157
 
    code = font_orig_scale(ofont, &sxo);
2158
 
    if (code < 0)
2159
 
        return code;
2160
 
    scale_c = sxc * 1000.0;
2161
 
    scale_o = sxo * 1000.0;
 
2160
    code = pdf_font_orig_matrix((const gs_font *)cfont, &scale_c);
 
2161
    if (code < 0)
 
2162
        return code;
 
2163
    code = pdf_font_orig_matrix(ofont, &scale_o);
 
2164
    if (code < 0)
 
2165
        return code;
 
2166
    gs_matrix_scale(&scale_c, 1000.0, 1000.0, &scale_c);
 
2167
    gs_matrix_scale(&scale_o, 1000.0, 1000.0, &scale_o);
2162
2168
    pwidths->Width.v.x = pwidths->Width.v.y = 0;
2163
2169
    pwidths->real_width.v.x = pwidths->real_width.v.y = 0;
2164
2170
    pwidths->replaced_v = false;
2165
2171
    if (glyph == GS_NO_GLYPH)
2166
 
        return get_missing_width(cfont, wmode, scale_c, pwidths);
 
2172
        return get_missing_width(cfont, wmode, &scale_c, pwidths);
2167
2173
    code = cfont->procs.glyph_info((gs_font *)cfont, glyph, NULL,
2168
2174
                                    GLYPH_INFO_WIDTH0 |
2169
2175
                                    (GLYPH_INFO_WIDTH0 << wmode) |
2175
2181
       So make a compatibe data here.
2176
2182
     */
2177
2183
    if (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode))) {
2178
 
        code = get_missing_width(cfont, wmode, scale_c, pwidths);
 
2184
        code = get_missing_width(cfont, wmode, &scale_c, pwidths);
2179
2185
        if (code < 0)
2180
2186
            v.y = 0;
2181
2187
        else 
2183
2189
        if (wmode && pdf_is_CID_font(ofont)) {
2184
2190
            pdf_glyph_widths_t widths1;
2185
2191
 
2186
 
            if (get_missing_width(cfont, 0, scale_c, &widths1) < 0)
 
2192
            if (get_missing_width(cfont, 0, &scale_c, &widths1) < 0)
2187
2193
                v.x = 0;
2188
2194
            else
2189
2195
                v.x = widths1.Width.w / 2;
2192
2198
    } else if (code < 0)
2193
2199
        return code;
2194
2200
    else {
2195
 
        code = store_glyph_width(&pwidths->Width, wmode, scale_c, &info);
 
2201
        code = store_glyph_width(&pwidths->Width, wmode, &scale_c, &info);
2196
2202
        if (code < 0)
2197
2203
            return code;
2198
2204
        rcode |= code;
2199
 
        if (info.members & (GLYPH_INFO_VVECTOR0 << wmode)) {
2200
 
            v.y = info.v.y * scale_c;
2201
 
        } else
2202
 
            v.y = 0;
 
2205
        if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode))
 
2206
            gs_distance_transform(info.v.x, info.v.y, &scale_c, &v);
 
2207
        else 
 
2208
            v.x = v.y = 0;
2203
2209
        if (wmode && pdf_is_CID_font(ofont)) {
2204
2210
            if (info.members & (GLYPH_INFO_WIDTH0 << wmode)) {
2205
 
                v.x = info.width[0].x * scale_c / 2;
 
2211
                gs_point xy;
 
2212
 
 
2213
                gs_distance_transform(info.width[0].x, info.width[0].y, &scale_c, &xy);
 
2214
                v.x = xy.x / 2;
2206
2215
            } else {
2207
2216
                pdf_glyph_widths_t widths1;
2208
2217
                
2209
 
                if (get_missing_width(cfont, 0, scale_c, &widths1) < 0)
 
2218
                if (get_missing_width(cfont, 0, &scale_c, &widths1) < 0)
2210
2219
                    v.x = 0;
2211
2220
                else
2212
2221
                    v.x = widths1.Width.w / 2;
2213
2222
            }
2214
 
        } else {
2215
 
            if (info.members  & (GLYPH_INFO_VVECTOR0 << wmode)) {
2216
 
                v.x = info.v.x * scale_c;
2217
 
            } else
2218
 
                v.x = 0;
2219
2223
        }
2220
2224
    }
2221
2225
    pwidths->Width.v = v;
2259
2263
            pwidths->replaced_v = true;
2260
2264
        else 
2261
2265
            info.v.x = info.v.y = 0;
2262
 
        code = store_glyph_width(&pwidths->real_width, wmode, scale_o, &info);
 
2266
        code = store_glyph_width(&pwidths->real_width, wmode, &scale_o, &info);
2263
2267
        if (code < 0)
2264
2268
            return code;
2265
2269
        rcode |= code;
2266
 
        pwidths->real_width.v.x = info.v.x * scale_o;
2267
 
        pwidths->real_width.v.y = info.v.y * scale_o;
 
2270
        gs_distance_transform(info.v.x, info.v.y, &scale_o, &pwidths->real_width.v);
2268
2271
    }
2269
2272
    return rcode;
2270
2273
}
2271
2274
 
2272
 
private int
 
2275
static int
2273
2276
pdf_choose_output_char_code(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_char *pch)
2274
2277
{
2275
2278
    gs_char ch;
2315
2318
    return 0;
2316
2319
}
2317
2320
 
2318
 
private int
 
2321
static int
2319
2322
pdf_choose_output_glyph_hame(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_const_string *gnstr, gs_glyph glyph)
2320
2323
{
2321
2324
    if (penum->orig_font->FontType == ft_composite) {
2382
2385
        gs_glyph glyphs[BUF_SIZE / sizeof(gs_glyph)];
2383
2386
    } buf;
2384
2387
 
2385
 
    if (!penum->pte_default && !penum->charproc_accum) {
 
2388
     if (!penum->pte_default && !penum->charproc_accum) {
2386
2389
        /* Don't need to sync before exiting charproc. */
2387
2390
        code = pdf_prepare_text_drawing(pdev, pte);
2388
2391
        if (code == gs_error_rangecheck) {
2414
2417
            code = pdf_choose_output_glyph_hame(pdev, penum, &gnstr, pte_default->returned.current_glyph);
2415
2418
            if (code < 0)
2416
2419
                return code;
 
2420
 
 
2421
            if ((penum->current_font->FontType == ft_user_defined) && stell(pdev->strm) == 0)
 
2422
            {
 
2423
                char glyph[256], FontName[gs_font_name_max + 1], KeyName[256];
 
2424
                int len;
 
2425
 
 
2426
                len = min(gs_font_name_max, gnstr.size);
 
2427
                memcpy(glyph, gnstr.data, len);
 
2428
                glyph[len] = 0x00;
 
2429
                len = min(255, penum->current_font->font_name.size);
 
2430
                memcpy(FontName, penum->current_font->font_name.chars, len);
 
2431
                FontName[len] = 0x00;
 
2432
                len = min(255, penum->current_font->key_name.size);
 
2433
                memcpy(KeyName, penum->current_font->key_name.chars, len);
 
2434
                KeyName[len] = 0x00;
 
2435
 
 
2436
                eprintf4("ERROR: Page %d used undefined glyph '%s' from type 3 font '%s', key '%s'\n",
 
2437
                    pdev->next_page, glyph, FontName, KeyName);
 
2438
                stream_puts(pdev->strm, "0 0 0 0 0 0 d1\n");
 
2439
            }
 
2440
            
2417
2441
            code = pdf_end_charproc_accum(pdev, penum->current_font, penum->cgp, 
2418
2442
                        pte_default->returned.current_glyph, penum->output_char_code, &gnstr);
2419
2443
            if (code < 0)
2530
2554
    else
2531
2555
        goto skip;
2532
2556
 
 
2557
    /* Now that we are using the working buffer for text in composite fonts, we must make sure
 
2558
     * it is large enough. Each input character code may be promoted to a gs_glyph, in scan_cmap_text
 
2559
     * when processing a Type 0 font with a type 1 descendant font. This routine uses
 
2560
     * pdf_make_text_glyphs_table_unencoded (called from pdf_obtain_font_resource_unencoded) which  
 
2561
     * also may require an identically sized buffer, so we need:
 
2562
     * num__input_characters * sizeof(gs_glyph) * 2.
 
2563
     */
 
2564
    if (pte->orig_font->FontType == ft_composite) {
 
2565
        if (size < (pte->text.size - pte->index) * sizeof(gs_glyph) * 2)
 
2566
            size = (pte->text.size - pte->index) * sizeof(gs_glyph) * 2;
 
2567
    }
 
2568
 
2533
2569
    if (size <= sizeof(buf)) {
2534
2570
        code = process(pte, buf.bytes, size);
2535
2571
    } else {