Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gxshade4.c,v 1.30 2005/04/19 12:22:08 igor Exp $ */
18
/* Rendering for Gouraud triangle shadings */
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gsmatrix.h"		/* for gscoord.h */
24
#include "gscoord.h"
25
#include "gsptype2.h"
26
#include "gxcspace.h"
27
#include "gxdcolor.h"
28
#include "gxdevcli.h"
29
#include "gxistate.h"
30
#include "gxpath.h"
31
#include "gxshade.h"
32
#include "gxshade4.h"
33
#include "vdtrace.h"
34
 
35
#define VD_TRACE_TRIANGLE_PATCH 1
36
 
37
/* Initialize the fill state for triangle shading. */
38
int
39
mesh_init_fill_state(mesh_fill_state_t * pfs, const gs_shading_mesh_t * psh,
40
		     const gs_fixed_rect * rect_clip, gx_device * dev,
41
		     gs_imager_state * pis)
42
{
43
    shade_init_fill_state((shading_fill_state_t *) pfs,
44
			  (const gs_shading_t *)psh, dev, pis);
45
    pfs->pshm = psh;
46
    pfs->rect = *rect_clip;
47
    return 0;
48
}
49
 
50
/* ---------------- Gouraud triangle shadings ---------------- */
51
 
52
private int
53
Gt_next_vertex(const gs_shading_mesh_t * psh, shade_coord_stream_t * cs,
54
	       shading_vertex_t * vertex)
55
{
56
    int code = shade_next_vertex(cs, vertex);
57
 
58
    if (code >= 0 && psh->params.Function) {
59
	vertex->c.t[0] = vertex->c.cc.paint.values[0];
60
	vertex->c.t[1] = 0;
61
	/* Decode the color with the function. */
62
	code = gs_function_evaluate(psh->params.Function, vertex->c.t,
63
				    vertex->c.cc.paint.values);
64
    }
65
    return code;
66
}
67
 
68
inline private int
69
Gt_fill_triangle(mesh_fill_state_t * pfs, const shading_vertex_t * va,
70
		 const shading_vertex_t * vb, const shading_vertex_t * vc)
71
{
72
    patch_fill_state_t pfs1;
73
    int code = 0;
74
 
75
    memcpy(&pfs1, (shading_fill_state_t *)pfs, sizeof(shading_fill_state_t));
76
    pfs1.Function = pfs->pshm->params.Function;
77
    pfs1.rect = pfs->rect;
78
    code = init_patch_fill_state(&pfs1);
79
    if (code < 0)
80
	return code;
81
    if (INTERPATCH_PADDING) {
82
	code = mesh_padding(&pfs1, &va->p, &vb->p, &va->c, &vb->c);
83
	if (code >= 0)
84
	    code = mesh_padding(&pfs1, &vb->p, &vc->p, &vb->c, &vc->c);
85
	if (code >= 0)
86
	    code = mesh_padding(&pfs1, &vc->p, &va->p, &vc->c, &va->c);
87
    }
88
    if (code >= 0)
89
	code = mesh_triangle(&pfs1, va, vb, vc);
90
    term_patch_fill_state(&pfs1);
91
    return code;
92
}
93
 
94
int
95
gs_shading_FfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
96
			       const gs_fixed_rect * rect_clip,
97
			       gx_device * dev, gs_imager_state * pis)
98
{
99
    const gs_shading_FfGt_t * const psh = (const gs_shading_FfGt_t *)psh0;
100
    mesh_fill_state_t state;
101
    shade_coord_stream_t cs;
102
    int num_bits = psh->params.BitsPerFlag;
103
    int flag;
104
    shading_vertex_t va, vb, vc;
105
    int code;
106
 
107
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) {
108
	vd_get_dc('s');
109
	vd_set_shift(0, 0);
110
	vd_set_scale(0.01);
111
	vd_set_origin(0, 0);
112
    }
113
    code = mesh_init_fill_state(&state, (const gs_shading_mesh_t *)psh, rect_clip,
114
			 dev, pis);
115
    if (code < 0)
116
	return code;
117
    shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
118
		    pis);
119
    while ((flag = shade_next_flag(&cs, num_bits)) >= 0) {
120
	switch (flag) {
121
	    default:
122
		return_error(gs_error_rangecheck);
123
	    case 0:
124
		if ((code = Gt_next_vertex(state.pshm, &cs, &va)) < 0 ||
125
		    (code = shade_next_flag(&cs, num_bits)) < 0 ||
126
		    (code = Gt_next_vertex(state.pshm, &cs, &vb)) < 0 ||
127
		    (code = shade_next_flag(&cs, num_bits)) < 0
128
		    )
129
		    return code;
130
		goto v2;
131
	    case 1:
132
		va = vb;
133
	    case 2:
134
		vb = vc;
135
v2:		if ((code = Gt_next_vertex(state.pshm, &cs, &vc)) < 0)
136
		    return code;
137
		if ((code = Gt_fill_triangle(&state, &va, &vb, &vc)) < 0)
138
		    return code;
139
	}
140
    }
141
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
142
	vd_release_dc;
143
    if (!cs.is_eod(&cs))
144
	return_error(gs_error_rangecheck);
145
    return 0;
146
}
147
 
148
int
149
gs_shading_LfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
150
			       const gs_fixed_rect * rect_clip,
151
			       gx_device * dev, gs_imager_state * pis)
152
{
153
    const gs_shading_LfGt_t * const psh = (const gs_shading_LfGt_t *)psh0;
154
    mesh_fill_state_t state;
155
    shade_coord_stream_t cs;
156
    shading_vertex_t *vertex;
157
    shading_vertex_t next;
158
    int per_row = psh->params.VerticesPerRow;
159
    int i, code;
160
 
161
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) {
162
	vd_get_dc('s');
163
	vd_set_shift(0, 0);
164
	vd_set_scale(0.01);
165
	vd_set_origin(0, 0);
166
    }
167
    code = mesh_init_fill_state(&state, (const gs_shading_mesh_t *)psh, rect_clip,
168
			 dev, pis);
169
    if (code < 0)
170
	return code;
171
    shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
172
		    pis);
173
    vertex = (shading_vertex_t *)
174
	gs_alloc_byte_array(pis->memory, per_row, sizeof(*vertex),
175
			    "gs_shading_LfGt_render");
176
    if (vertex == 0)
177
	return_error(gs_error_VMerror);
178
    for (i = 0; i < per_row; ++i)
179
	if ((code = Gt_next_vertex(state.pshm, &cs, &vertex[i])) < 0)
180
	    goto out;
181
    while (!seofp(cs.s)) {
182
	code = Gt_next_vertex(state.pshm, &cs, &next);
183
	if (code < 0)
184
	    goto out;
185
	for (i = 1; i < per_row; ++i) {
186
	    code = Gt_fill_triangle(&state, &vertex[i - 1], &vertex[i], &next);
187
	    if (code < 0)
188
		goto out;
189
	    vertex[i - 1] = next;
190
	    code = Gt_next_vertex(state.pshm, &cs, &next);
191
	    if (code < 0)
192
		goto out;
193
	    code = Gt_fill_triangle(&state, &vertex[i], &vertex[i - 1], &next);
194
	    if (code < 0)
195
		goto out;
196
	}
197
	vertex[per_row - 1] = next;
198
    }
199
out:
200
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
201
	vd_release_dc;
202
    gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render");
203
    return code;
204
}