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

« back to all changes in this revision

Viewing changes to src/gdevpdfg.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: gdevpdfg.c 8022 2007-06-05 22:23:38Z giles $ */
 
14
/* $Id: gdevpdfg.c 8265 2007-10-02 07:31:58Z ken $ */
15
15
/* Graphics state management for pdfwrite driver */
16
16
#include "math_.h"
17
17
#include "string_.h"
78
78
}
79
79
 
80
80
/* Load the viewer's graphic state. */
81
 
private void
 
81
static void
82
82
pdf_load_viewer_state(gx_device_pdf *pdev, pdf_viewer_state *s)
83
83
{   
84
84
    pdev->transfer_ids[0] = s->transfer_ids[0];
140
140
}
141
141
 
142
142
/* Prepare intitial values for viewer's graphics state parameters. */
143
 
private void
 
143
static void
144
144
pdf_viewer_state_from_imager_state_aux(pdf_viewer_state *pvs, const gs_imager_state *pis)
145
145
{
146
146
    pvs->transfer_not_identity = 
215
215
 
216
216
/* Reset the graphics state parameters to initial values. */
217
217
/* Used if pdf_prepare_initial_viewer_state was not callad. */
218
 
private void
 
218
static void
219
219
pdf_reset_graphics_old(gx_device_pdf * pdev)
220
220
{
221
221
 
246
246
}
247
247
 
248
248
/* Write client color. */
249
 
private int
 
249
static int
250
250
pdf_write_ccolor(gx_device_pdf * pdev, const gs_imager_state * pis, 
251
251
                const gs_client_color *pcc)
252
252
{   
259
259
    return 0;
260
260
}
261
261
 
262
 
private inline bool
 
262
static inline bool
263
263
is_cspace_allowed_in_strategy(gx_device_pdf * pdev, gs_color_space_index csi)
264
264
{
265
265
    if (pdev->params.ColorConversionStrategy == ccs_CMYK && 
276
276
    return true;
277
277
}
278
278
 
279
 
private inline bool
 
279
static inline bool
280
280
is_pattern2_allowed_in_strategy(gx_device_pdf * pdev, const gx_drawing_color *pdc)
281
281
{
282
282
    const gs_color_space *pcs2 = gx_dc_pattern2_get_color_space(pdc);
286
286
}
287
287
 
288
288
/* Set the fill or stroke color. */
289
 
private int
 
289
int
290
290
pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis, 
291
291
                const gx_drawing_color *pdc, gx_hl_saved_color * psc,
292
292
                bool *used_process_color,
293
293
                const psdf_set_color_commands_t *ppscc)
294
294
{
295
 
    int code;
 
295
    int code = 0;
296
296
    gx_hl_saved_color temp;
297
 
    bool process_color;
298
297
    const gs_color_space *pcs, *pcs2;
299
298
    const gs_client_color *pcc; /* fixme: not needed due to gx_hld_get_color_component. */
300
299
    cos_value_t cs_value;
304
303
 
305
304
    if (pdev->skip_colors)
306
305
        return 0;
307
 
    process_color = !gx_hld_save_color(pis, pdc, &temp);
 
306
    gx_hld_save_color(pis, pdc, &temp);
308
307
    /* Since pdfwrite never applies halftones and patterns, but monitors
309
308
     * halftone/pattern IDs separately, we don't need to compare
310
309
     * halftone/pattern bodies here.
311
310
     */
312
311
    if (gx_hld_saved_color_equal(&temp, psc))
313
312
        return 0;
314
 
    /*
315
 
     * In principle, we can set colors in either stream or text
316
 
     * context.  However, since we currently enclose all text
317
 
     * strings inside a gsave/grestore, this causes us to lose
318
 
     * track of the color when we leave text context.  Therefore,
319
 
     * we require stream context for setting colors.
320
 
     */
321
 
    code = pdf_open_page(pdev, PDF_IN_STREAM);
322
 
    if (code < 0)
323
 
        return code;
 
313
 
324
314
    switch (gx_hld_get_color_space_and_ccolor(pis, pdc, &pcs, &pcc)) {
325
315
        case non_pattern_color_space:
326
316
            switch (gs_color_space_get_index(pcs)) {
459
449
                      bool *used_process_color,
460
450
                      const psdf_set_color_commands_t *ppscc)
461
451
{
 
452
    gx_hl_saved_color temp;
 
453
    int code;
 
454
 
 
455
    /* This section of code was in pdf_reset_color above, but was moved into this 
 
456
     * routine (and below) in order to isolate the switch to a stream context. This
 
457
     * now allows us the opportunity to write colours in any context, in particular
 
458
     * when in a text context, by using pdf_reset_color.
 
459
     */
 
460
    if (pdev->skip_colors)
 
461
        return 0;
 
462
    gx_hld_save_color(pis, pdc, &temp);
 
463
    /* Since pdfwrite never applies halftones and patterns, but monitors
 
464
     * halftone/pattern IDs separately, we don't need to compare
 
465
     * halftone/pattern bodies here.
 
466
     */
 
467
    if (gx_hld_saved_color_equal(&temp, psc))
 
468
        return 0;
 
469
    /*
 
470
     * In principle, we can set colors in either stream or text
 
471
     * context.  However, since we currently enclose all text
 
472
     * strings inside a gsave/grestore, this causes us to lose
 
473
     * track of the color when we leave text context.  Therefore,
 
474
     * we require stream context for setting colors.
 
475
     */
 
476
    code = pdf_open_page(pdev, PDF_IN_STREAM);
 
477
    if (code < 0)
 
478
        return code;
 
479
 
462
480
    return pdf_reset_color(pdev, pis, pdc, psc, used_process_color, ppscc);
463
481
}
464
482
int
468
486
                   const psdf_set_color_commands_t *ppscc)
469
487
{
470
488
    gx_drawing_color dcolor;
 
489
    gx_hl_saved_color temp;
 
490
    int code;
471
491
 
472
492
    set_nonclient_dev_color(&dcolor, color);
 
493
 
 
494
    if (pdev->skip_colors)
 
495
        return 0;
 
496
    gx_hld_save_color(NULL, &dcolor, &temp);
 
497
    /* Since pdfwrite never applies halftones and patterns, but monitors
 
498
     * halftone/pattern IDs separately, we don't need to compare
 
499
     * halftone/pattern bodies here.
 
500
     */
 
501
    if (gx_hld_saved_color_equal(&temp, psc))
 
502
        return 0;
 
503
    /*
 
504
     * In principle, we can set colors in either stream or text
 
505
     * context.  However, since we currently enclose all text
 
506
     * strings inside a gsave/grestore, this causes us to lose
 
507
     * track of the color when we leave text context.  Therefore,
 
508
     * we require stream context for setting colors.
 
509
     */
 
510
    code = pdf_open_page(pdev, PDF_IN_STREAM);
 
511
    if (code < 0)
 
512
        return code;
 
513
 
473
514
    return pdf_reset_color(pdev, NULL, &dcolor, psc, used_process_color, ppscc);
474
515
}
475
516
 
505
546
 * an identity map.  Return 1 if the map is the identity map, otherwise
506
547
 * return 0.
507
548
 */
508
 
private data_source_proc_access(transfer_map_access); /* check prototype */
509
 
private int
 
549
static data_source_proc_access(transfer_map_access); /* check prototype */
 
550
static int
510
551
transfer_map_access(const gs_data_source_t *psrc, ulong start, uint length,
511
552
                    byte *buf, const byte **ptr)
512
553
{
519
560
        buf[i] = frac2byte(map->values[(uint)start + i]);
520
561
    return 0;
521
562
}
522
 
private int
 
563
static int
523
564
transfer_map_access_signed(const gs_data_source_t *psrc,
524
565
                           ulong start, uint length,
525
566
                           byte *buf, const byte **ptr)
539
580
            ((frac2float(map->values[(uint)start + i]) + 1) * 127);
540
581
    return 0;
541
582
}
542
 
private int
 
583
static int
543
584
pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
544
585
                       int range0, bool check_identity,
545
586
                       const char *key, char *ids)
614
655
    sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id);
615
656
    return 0;
616
657
}
617
 
private int
 
658
static int
618
659
pdf_write_transfer(gx_device_pdf *pdev, const gx_transfer_map *map,
619
660
                   const char *key, char *ids)
620
661
{
630
671
 * results.  Currently we only do this for a few of the functions.
631
672
 */
632
673
#define HT_FUNC(name, expr)\
633
 
  private floatp name(floatp xd, floatp yd) {\
 
674
  static floatp name(floatp xd, floatp yd) {\
634
675
    float x = (float)xd, y = (float)yd;\
635
676
    return d2f(expr);\
636
677
  }
640
681
 * doesn't actually do the coercion.  Force this here.  Note that if we
641
682
 * use 'inline', it doesn't work.
642
683
 */
643
 
private float
 
684
static float
644
685
d2f(floatp d)
645
686
{
646
687
    float f = (float)d;
647
688
    return f;
648
689
}
649
 
private floatp
 
690
static floatp
650
691
ht_Round(floatp xf, floatp yf)
651
692
{
652
693
    float x = (float)xf, y = (float)yf;
657
698
    xabs -= 1, yabs -= 1;
658
699
    return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
659
700
}
660
 
private floatp
 
701
static floatp
661
702
ht_Diamond(floatp xf, floatp yf)
662
703
{
663
704
    float x = (float)xf, y = (float)yf;
670
711
    xabs -= 1, yabs -= 1;
671
712
    return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
672
713
}
673
 
private floatp
 
714
static floatp
674
715
ht_Ellipse(floatp xf, floatp yf)
675
716
{
676
717
    float x = (float)xf, y = (float)yf;
696
737
 * Most of these are recognized properly even without d2f.  We've only
697
738
 * added d2f where it apparently makes a difference.
698
739
 */
699
 
private float
 
740
static float
700
741
d2fsin_d(double x) {
701
742
    return d2f(gs_sin_degrees(d2f(x)));
702
743
}
703
 
private float
 
744
static float
704
745
d2fcos_d(double x) {
705
746
    return d2f(gs_cos_degrees(d2f(x)));
706
747
}
726
767
    const char *fname;
727
768
    floatp (*proc)(floatp, floatp);
728
769
} ht_function_t;
729
 
private const ht_function_t ht_functions[] = {
 
770
static const ht_function_t ht_functions[] = {
730
771
    {"Round", ht_Round},
731
772
    {"Diamond", ht_Diamond},
732
773
    {"Ellipse", ht_Ellipse},
751
792
};
752
793
 
753
794
/* Write each kind of halftone. */
754
 
private int
 
795
static int
755
796
pdf_write_spot_function(gx_device_pdf *pdev, const gx_ht_order *porder,
756
797
                        long *pid)
757
798
{
820
861
    gs_free_object(mem, values, "pdf_write_spot_function");
821
862
    return code;
822
863
}
823
 
private int
 
864
static int
824
865
pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
825
866
                        const gx_ht_order *porder, long *pid)
826
867
{
889
930
    stream_puts(s, ">>\n");
890
931
    return pdf_end_separate(pdev);
891
932
}
892
 
private int
 
933
static int
893
934
pdf_write_screen_halftone(gx_device_pdf *pdev, const gs_screen_halftone *psht,
894
935
                          const gx_ht_order *porder, long *pid)
895
936
{
901
942
    spot.transfer_closure.proc = 0;
902
943
    return pdf_write_spot_halftone(pdev, &spot, porder, pid);
903
944
}
904
 
private int
 
945
static int
905
946
pdf_write_colorscreen_halftone(gx_device_pdf *pdev,
906
947
                               const gs_colorscreen_halftone *pcsht,
907
948
                               const gx_device_halftone *pdht, long *pid)
935
976
#define CHECK(expr)\
936
977
  BEGIN if ((code = (expr)) < 0) return code; END
937
978
 
938
 
private int
 
979
static int
939
980
pdf_write_threshold_halftone(gx_device_pdf *pdev,
940
981
                             const gs_threshold_halftone *ptht,
941
982
                             const gx_ht_order *porder, long *pid)
965
1006
    stream_write(writer.binary.strm, ptht->thresholds.data, ptht->thresholds.size);
966
1007
    return pdf_end_data(&writer);
967
1008
}
968
 
private int
 
1009
static int
969
1010
pdf_write_threshold2_halftone(gx_device_pdf *pdev,
970
1011
                              const gs_threshold2_halftone *ptht,
971
1012
                              const gx_ht_order *porder, long *pid)
1014
1055
    }
1015
1056
    return pdf_end_data(&writer);
1016
1057
}
1017
 
private int 
 
1058
static int 
1018
1059
pdf_get_halftone_component_index(const gs_multiple_halftone *pmht,
1019
1060
                                 const gx_device_halftone *pdht,
1020
1061
                                 int dht_index)
1034
1075
    }
1035
1076
    return j;
1036
1077
}
1037
 
private int
 
1078
static int
1038
1079
pdf_write_multiple_halftone(gx_device_pdf *pdev,
1039
1080
                            const gs_multiple_halftone *pmht,
1040
1081
                            const gx_device_halftone *pdht, long *pid)
1133
1174
 * Update the halftone.  This is a separate procedure only for
1134
1175
 * readability.
1135
1176
 */
1136
 
private int
 
1177
static int
1137
1178
pdf_update_halftone(gx_device_pdf *pdev, const gs_imager_state *pis,
1138
1179
                    char *hts)
1139
1180
{
1180
1221
 
1181
1222
/* ------ Graphics state updating ------ */
1182
1223
 
1183
 
private inline cos_dict_t *
 
1224
static inline cos_dict_t *
1184
1225
resource_dict(pdf_resource_t *pres)
1185
1226
{
1186
1227
    return (cos_dict_t *)pres->object;
1187
1228
}
1188
1229
 
1189
1230
/* Open an ExtGState. */
1190
 
private int
 
1231
static int
1191
1232
pdf_open_gstate(gx_device_pdf *pdev, pdf_resource_t **ppres)
1192
1233
{
1193
1234
    int code;
1238
1279
 * Update the transfer functions(s).  This is a separate procedure only
1239
1280
 * for readability.
1240
1281
 */
1241
 
private int
 
1282
static int
1242
1283
pdf_update_transfer(gx_device_pdf *pdev, const gs_imager_state *pis,
1243
1284
                    char *trs)
1244
1285
{
1295
1336
 * stores separate opacity and shape alpha, a rangecheck will occur if
1296
1337
 * both are different from the current setting.
1297
1338
 */
1298
 
private int
 
1339
static int
1299
1340
pdf_update_alpha(gx_device_pdf *pdev, const gs_imager_state *pis,
1300
1341
                 pdf_resource_t **ppres)
1301
1342
{
1559
1600
}
1560
1601
 
1561
1602
/* Update the graphics state for stroking. */
1562
 
private int
 
1603
static int
1563
1604
pdf_try_prepare_stroke(gx_device_pdf *pdev, const gs_imager_state *pis)
1564
1605
{
1565
1606
    pdf_resource_t *pres = 0;