diff options
-rw-r--r-- | base/gdevdrop.c | 429 | ||||
-rw-r--r-- | base/gdevmem.h | 22 |
2 files changed, 450 insertions, 1 deletions
diff --git a/base/gdevdrop.c b/base/gdevdrop.c index 7f70f4265..599f1740d 100644 --- a/base/gdevdrop.c +++ b/base/gdevdrop.c | |||
@@ -1013,3 +1013,432 @@ gs_transparent_rop(gs_logical_operation_t lop) | |||
1013 | #undef MPo | 1013 | #undef MPo |
1014 | return (rop & mask) | (rop3_D & ~mask); | 1014 | return (rop & mask) | (rop3_D & ~mask); |
1015 | } | 1015 | } |
1016 | |||
1017 | typedef enum | ||
1018 | { | ||
1019 | transform_pixel_region_portrait, | ||
1020 | transform_pixel_region_landscape, | ||
1021 | transform_pixel_region_skew | ||
1022 | } transform_pixel_region_posture; | ||
1023 | |||
1024 | typedef struct mem_transform_pixel_region_state_s mem_transform_pixel_region_state_t; | ||
1025 | |||
1026 | typedef int (mem_transform_pixel_region_render_fn)(gx_device *dev, mem_transform_pixel_region_state_t *state, const unsigned char **buffer, int data_x, gx_cmapper_t *cmapper, const gs_gstate *pgs); | ||
1027 | |||
1028 | struct mem_transform_pixel_region_state_s | ||
1029 | { | ||
1030 | gs_memory_t *mem; | ||
1031 | gx_dda_fixed_point pixels; | ||
1032 | gx_dda_fixed_point rows; | ||
1033 | gs_int_rect clip; | ||
1034 | int w; | ||
1035 | int h; | ||
1036 | int spp; | ||
1037 | transform_pixel_region_posture posture; | ||
1038 | mem_transform_pixel_region_render_fn *render; | ||
1039 | void *passthru; | ||
1040 | }; | ||
1041 | |||
1042 | static void | ||
1043 | get_portrait_y_extent(mem_transform_pixel_region_state_t *state, int *iy, int *ih) | ||
1044 | { | ||
1045 | fixed y0, y1; | ||
1046 | gx_dda_fixed row = state->rows.y; | ||
1047 | |||
1048 | y0 = dda_current(row); | ||
1049 | dda_next(row); | ||
1050 | y1 = dda_current(row); | ||
1051 | |||
1052 | if (y1 < y0) { | ||
1053 | fixed t = y1; y1 = y0; y0 = t; | ||
1054 | } | ||
1055 | |||
1056 | *iy = fixed2int_pixround_perfect(y0); | ||
1057 | *ih = fixed2int_pixround_perfect(y1) - *iy; | ||
1058 | } | ||
1059 | |||
1060 | static void | ||
1061 | get_landscape_x_extent(mem_transform_pixel_region_state_t *state, int *ix, int *iw) | ||
1062 | { | ||
1063 | fixed x0, x1; | ||
1064 | gx_dda_fixed row = state->rows.x; | ||
1065 | |||
1066 | x0 = dda_current(row); | ||
1067 | dda_next(row); | ||
1068 | x1 = dda_current(row); | ||
1069 | |||
1070 | if (x1 < x0) { | ||
1071 | fixed t = x1; x1 = x0; x0 = t; | ||
1072 | } | ||
1073 | |||
1074 | *ix = fixed2int_pixround_perfect(x0); | ||
1075 | *iw = fixed2int_pixround_perfect(x1) - *ix; | ||
1076 | } | ||
1077 | |||
1078 | static int | ||
1079 | mem_transform_pixel_region_render_portrait(gx_device *dev, mem_transform_pixel_region_state_t *state, const unsigned char **buffer, int data_x, gx_cmapper_t *cmapper, const gs_gstate *pgs) | ||
1080 | { | ||
1081 | gx_device_memory *mdev = (gx_device_memory *)dev; | ||
1082 | gx_dda_fixed_point pnext; | ||
1083 | int vci, vdi; | ||
1084 | int irun; /* int x/rrun */ | ||
1085 | int w = state->w; | ||
1086 | int h = state->h; | ||
1087 | int spp = state->spp; | ||
1088 | const byte *data = buffer[0] + data_x * spp; | ||
1089 | const byte *bufend = NULL; | ||
1090 | int code = 0; | ||
1091 | const byte *run; | ||
1092 | int k; | ||
1093 | gx_color_value *conc = &cmapper->conc[0]; | ||
1094 | gx_cmapper_fn *mapper = cmapper->set_color; | ||
1095 | byte *out; | ||
1096 | byte *out_row; | ||
1097 | int minx, maxx; | ||
1098 | |||
1099 | if (h == 0) | ||
1100 | return 0; | ||
1101 | |||
1102 | /* Clip on y */ | ||
1103 | get_portrait_y_extent(state, &vci, &vdi); | ||
1104 | if (vci < state->clip.p.y) | ||
1105 | vdi += vci - state->clip.p.y, vci = state->clip.p.y; | ||
1106 | if (vci+vdi > state->clip.q.y) | ||
1107 | vdi = state->clip.q.y - vci; | ||
1108 | if (vdi <= 0) | ||
1109 | return 0; | ||
1110 | |||
1111 | pnext = state->pixels; | ||
1112 | irun = fixed2int_var_rounded(dda_current(pnext.x)); | ||
1113 | dda_translate(pnext.x, (-fixed_epsilon)); | ||
1114 | if_debug5m('b', dev->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", | ||
1115 | vci, data_x, w, fixed2float(dda_current(pnext.x)), fixed2float(dda_current(pnext.y))); | ||
1116 | |||
1117 | minx = state->clip.p.x; | ||
1118 | maxx = state->clip.q.x; | ||
1119 | out_row = mdev->base + mdev->raster * vci; | ||
1120 | bufend = data + w * spp; | ||
1121 | while (data < bufend) { | ||
1122 | /* Find the length of the next run. It will either end when we hit | ||
1123 | * the end of the source data, or when the pixel data differs. */ | ||
1124 | run = data + spp; | ||
1125 | while (1) | ||
1126 | { | ||
1127 | dda_next(pnext.x); | ||
1128 | if (run >= bufend) | ||
1129 | break; | ||
1130 | if (memcmp(run, data, spp)) | ||
1131 | break; | ||
1132 | run += spp; | ||
1133 | } | ||
1134 | /* So we have a run of pixels from data to run that are all the same. */ | ||
1135 | /* This needs to be sped up */ | ||
1136 | for (k = 0; k < spp; k++) { | ||
1137 | conc[k] = gx_color_value_from_byte(data[k]); | ||
1138 | } | ||
1139 | mapper(cmapper); | ||
1140 | /* Fill the region between irun and fixed2int_var_rounded(pnext.x) */ | ||
1141 | { | ||
1142 | int xi = irun; | ||
1143 | int wi = (irun = fixed2int_var_rounded(dda_current(pnext.x))) - xi; | ||
1144 | |||
1145 | if (wi < 0) | ||
1146 | xi += wi, wi = -wi; | ||
1147 | |||
1148 | if (xi < minx) | ||
1149 | wi += xi - minx, xi = minx; | ||
1150 | if (xi+wi > maxx) | ||
1151 | wi = maxx - xi; | ||
1152 | if (wi > 0) { | ||
1153 | /* assert(color_is_pure(&cmapper->devc)); */ | ||
1154 | out = out_row; | ||
1155 | for (h = vdi; h > 0; h--, out += mdev->raster) { | ||
1156 | gx_color_index color = cmapper->devc.colors.pure; | ||
1157 | int xii = xi * spp; | ||
1158 | int wii = wi; | ||
1159 | do { | ||
1160 | /* Excuse the double shifts below, that's to stop the | ||
1161 | * C compiler complaining if the color index type is | ||
1162 | * 32 bits. */ | ||
1163 | switch(spp) | ||
1164 | { | ||
1165 | case 8: out[xii++] = ((color>>28)>>28) & 0xff; | ||
1166 | case 7: out[xii++] = ((color>>24)>>24) & 0xff; | ||
1167 | case 6: out[xii++] = ((color>>24)>>16) & 0xff; | ||
1168 | case 5: out[xii++] = ((color>>24)>>8) & 0xff; | ||
1169 | case 4: out[xii++] = (color>>24) & 0xff; | ||
1170 | case 3: out[xii++] = (color>>16) & 0xff; | ||
1171 | case 2: out[xii++] = (color>>8) & 0xff; | ||
1172 | case 1: out[xii++] = color & 0xff; | ||
1173 | } | ||
1174 | } while (--wii != 0); | ||
1175 | } | ||
1176 | } | ||
1177 | } | ||
1178 | data = run; | ||
1179 | } | ||
1180 | return (code < 0 ? code : 1); | ||
1181 | /* Save position if error, in case we resume. */ | ||
1182 | } | ||
1183 | |||
1184 | static int | ||
1185 | mem_transform_pixel_region_render_landscape(gx_device *dev, mem_transform_pixel_region_state_t *state, const unsigned char **buffer, int data_x, gx_cmapper_t *cmapper, const gs_gstate *pgs) | ||
1186 | { | ||
1187 | gx_device_memory *mdev = (gx_device_memory *)dev; | ||
1188 | gx_dda_fixed_point pnext; | ||
1189 | int vci, vdi; | ||
1190 | int irun; /* int x/rrun */ | ||
1191 | int w = state->w; | ||
1192 | int h = state->h; | ||
1193 | int spp = state->spp; | ||
1194 | const byte *data = buffer[0] + data_x * spp; | ||
1195 | const byte *bufend = NULL; | ||
1196 | int code = 0; | ||
1197 | const byte *run; | ||
1198 | int k; | ||
1199 | gx_color_value *conc = &cmapper->conc[0]; | ||
1200 | gx_cmapper_fn *mapper = cmapper->set_color; | ||
1201 | byte *out; | ||
1202 | byte *out_row; | ||
1203 | int miny, maxy; | ||
1204 | |||
1205 | if (h == 0) | ||
1206 | return 0; | ||
1207 | |||
1208 | /* Clip on x */ | ||
1209 | get_landscape_x_extent(state, &vci, &vdi); | ||
1210 | if (vci < state->clip.p.x) | ||
1211 | vdi += vci - state->clip.p.x, vci = state->clip.p.x; | ||
1212 | if (vci+vdi > state->clip.q.x) | ||
1213 | vdi = state->clip.q.x - vci; | ||
1214 | if (vdi <= 0) | ||
1215 | return 0; | ||
1216 | |||
1217 | pnext = state->pixels; | ||
1218 | irun = fixed2int_var_rounded(dda_current(pnext.y)); | ||
1219 | dda_translate(pnext.x, (-fixed_epsilon)); | ||
1220 | if_debug5m('b', dev->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", | ||
1221 | vci, data_x, w, fixed2float(dda_current(pnext.x)), fixed2float(dda_current(pnext.y))); | ||
1222 | |||
1223 | miny = state->clip.p.y; | ||
1224 | maxy = state->clip.q.y; | ||
1225 | out_row = mdev->base + vci * spp; | ||
1226 | bufend = data + w * spp; | ||
1227 | while (data < bufend) { | ||
1228 | /* Find the length of the next run. It will either end when we hit | ||
1229 | * the end of the source data, or when the pixel data differs. */ | ||
1230 | run = data + spp; | ||
1231 | while (1) | ||
1232 | { | ||
1233 | dda_next(pnext.y); | ||
1234 | if (run >= bufend) | ||
1235 | break; | ||
1236 | if (memcmp(run, data, spp)) | ||
1237 | break; | ||
1238 | run += spp; | ||
1239 | } | ||
1240 | /* So we have a run of pixels from data to run that are all the same. */ | ||
1241 | /* This needs to be sped up */ | ||
1242 | for (k = 0; k < spp; k++) { | ||
1243 | conc[k] = gx_color_value_from_byte(data[k]); | ||
1244 | } | ||
1245 | mapper(cmapper); | ||
1246 | /* Fill the region between irun and fixed2int_var_rounded(pnext.y) */ | ||
1247 | { /* 90 degree rotated rectangle */ | ||
1248 | int yi = irun; | ||
1249 | int hi = (irun = fixed2int_var_rounded(dda_current(pnext.y))) - yi; | ||
1250 | |||
1251 | if (hi < 0) | ||
1252 | yi += hi, hi = -hi; | ||
1253 | |||
1254 | if (yi < miny) | ||
1255 | hi += yi - miny, yi = miny; | ||
1256 | if (yi+hi > maxy) | ||
1257 | hi = maxy - yi; | ||
1258 | if (hi > 0) { | ||
1259 | /* assert(color_is_pure(&cmapper->devc)); */ | ||
1260 | out = out_row + mdev->raster * yi; | ||
1261 | for (h = hi; h > 0; h--, out += mdev->raster) { | ||
1262 | gx_color_index color = cmapper->devc.colors.pure; | ||
1263 | int xii = 0; | ||
1264 | int wii = vdi; | ||
1265 | do { | ||
1266 | /* Excuse the double shifts below, that's to stop the | ||
1267 | * C compiler complaining if the color index type is | ||
1268 | * 32 bits. */ | ||
1269 | switch(spp) | ||
1270 | { | ||
1271 | case 8: out[xii++] = ((color>>28)>>28) & 0xff; | ||
1272 | case 7: out[xii++] = ((color>>24)>>24) & 0xff; | ||
1273 | case 6: out[xii++] = ((color>>24)>>16) & 0xff; | ||
1274 | case 5: out[xii++] = ((color>>24)>>8) & 0xff; | ||
1275 | case 4: out[xii++] = (color>>24) & 0xff; | ||
1276 | case 3: out[xii++] = (color>>16) & 0xff; | ||
1277 | case 2: out[xii++] = (color>>8) & 0xff; | ||
1278 | case 1: out[xii++] = color & 0xff; | ||
1279 | } | ||
1280 | } while (--wii != 0); | ||
1281 | } | ||
1282 | } | ||
1283 | } | ||
1284 | if (code < 0) | ||
1285 | goto err; | ||
1286 | data = run; | ||
1287 | } | ||
1288 | return (code < 0 ? code : 1); | ||
1289 | /* Save position if error, in case we resume. */ | ||
1290 | err: | ||
1291 | buffer[0] = run; | ||
1292 | return code; | ||
1293 | } | ||
1294 | |||
1295 | static int | ||
1296 | mem_transform_pixel_region_begin(gx_device *dev, int w, int h, int spp, | ||
1297 | const gx_dda_fixed_point *pixels, const gx_dda_fixed_point *rows, | ||
1298 | const gs_int_rect *clip, transform_pixel_region_posture posture, | ||
1299 | mem_transform_pixel_region_state_t **statep) | ||
1300 | { | ||
1301 | mem_transform_pixel_region_state_t *state; | ||
1302 | gs_memory_t *mem = dev->memory->non_gc_memory; | ||
1303 | *statep = state = (mem_transform_pixel_region_state_t *)gs_alloc_bytes(mem, sizeof(mem_transform_pixel_region_state_t), "mem_transform_pixel_region_state_t"); | ||
1304 | if (state == NULL) | ||
1305 | return gs_error_VMerror; | ||
1306 | state->mem = mem; | ||
1307 | state->rows = *rows; | ||
1308 | state->pixels = *pixels; | ||
1309 | state->clip = *clip; | ||
1310 | if (state->clip.p.x < 0) | ||
1311 | state->clip.p.x = 0; | ||
1312 | if (state->clip.q.x > dev->width) | ||
1313 | state->clip.q.x = dev->width; | ||
1314 | if (state->clip.p.y < 0) | ||
1315 | state->clip.p.y = 0; | ||
1316 | if (state->clip.q.y > dev->height) | ||
1317 | state->clip.q.y = dev->height; | ||
1318 | state->w = w; | ||
1319 | state->h = h; | ||
1320 | state->spp = spp; | ||
1321 | state->posture = posture; | ||
1322 | |||
1323 | if (state->posture == transform_pixel_region_portrait) | ||
1324 | state->render = mem_transform_pixel_region_render_portrait; | ||
1325 | else | ||
1326 | state->render = mem_transform_pixel_region_render_landscape; | ||
1327 | |||
1328 | return 0; | ||
1329 | } | ||
1330 | |||
1331 | static void | ||
1332 | step_to_next_line(mem_transform_pixel_region_state_t *state) | ||
1333 | { | ||
1334 | fixed x = dda_current(state->rows.x); | ||
1335 | fixed y = dda_current(state->rows.y); | ||
1336 | dda_next(state->rows.x); | ||
1337 | dda_next(state->rows.y); | ||
1338 | x = dda_current(state->rows.x) - x; | ||
1339 | y = dda_current(state->rows.y) - y; | ||
1340 | dda_translate(state->pixels.x, x); | ||
1341 | dda_translate(state->pixels.y, y); | ||
1342 | } | ||
1343 | |||
1344 | static int | ||
1345 | mem_transform_pixel_region_data_needed(gx_device *dev, mem_transform_pixel_region_state_t *state) | ||
1346 | { | ||
1347 | if (state->posture == transform_pixel_region_portrait) { | ||
1348 | int iy, ih; | ||
1349 | |||
1350 | get_portrait_y_extent(state, &iy, &ih); | ||
1351 | |||
1352 | if (iy + ih < state->clip.p.y || iy >= state->clip.q.y) { | ||
1353 | /* Skip this line. */ | ||
1354 | step_to_next_line(state); | ||
1355 | return 0; | ||
1356 | } | ||
1357 | } else if (state->posture == transform_pixel_region_landscape) { | ||
1358 | int ix, iw; | ||
1359 | |||
1360 | get_landscape_x_extent(state, &ix, &iw); | ||
1361 | |||
1362 | if (ix + iw < state->clip.p.x || ix >= state->clip.q.x) { | ||
1363 | /* Skip this line. */ | ||
1364 | step_to_next_line(state); | ||
1365 | return 0; | ||
1366 | } | ||
1367 | } | ||
1368 | |||
1369 | return 1; | ||
1370 | } | ||
1371 | |||
1372 | static int | ||
1373 | mem_transform_pixel_region_process_data(gx_device *dev, mem_transform_pixel_region_state_t *state, const unsigned char **buffer, int data_x, gx_cmapper_t *cmapper, const gs_gstate *pgs) | ||
1374 | { | ||
1375 | int ret = state->render(dev, state, buffer, data_x, cmapper, pgs); | ||
1376 | step_to_next_line(state); | ||
1377 | return ret; | ||
1378 | } | ||
1379 | |||
1380 | static int | ||
1381 | mem_transform_pixel_region_end(gx_device *dev, mem_transform_pixel_region_state_t *state) | ||
1382 | { | ||
1383 | if (state) | ||
1384 | gs_free_object(state->mem->non_gc_memory, state, "mem_transform_pixel_region_state_t"); | ||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | int mem_transform_pixel_region(gx_device *dev, transform_pixel_region_reason reason, transform_pixel_region_data *data) | ||
1389 | { | ||
1390 | mem_transform_pixel_region_state_t *state = (mem_transform_pixel_region_state_t *)data->state; | ||
1391 | transform_pixel_region_posture posture; | ||
1392 | |||
1393 | /* Pass through */ | ||
1394 | if (reason == transform_pixel_region_begin) { | ||
1395 | const gx_dda_fixed_point *rows = data->u.init.rows; | ||
1396 | const gx_dda_fixed_point *pixels = data->u.init.pixels; | ||
1397 | if (rows->x.step.dQ == 0 && rows->x.step.dR == 0 && pixels->y.step.dQ == 0 && pixels->y.step.dR == 0) | ||
1398 | posture = transform_pixel_region_portrait; | ||
1399 | else if (rows->y.step.dQ == 0 && rows->y.step.dR == 0 && pixels->x.step.dQ == 0 && pixels->x.step.dR == 0) | ||
1400 | posture = transform_pixel_region_landscape; | ||
1401 | else | ||
1402 | posture = transform_pixel_region_skew; | ||
1403 | |||
1404 | if (posture == transform_pixel_region_skew || dev->color_info.depth != data->u.init.spp*8 || data->u.init.lop != 0xf0) { | ||
1405 | mem_transform_pixel_region_state_t *state = (mem_transform_pixel_region_state_t *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(mem_transform_pixel_region_state_t), "mem_transform_pixel_region_state_t"); | ||
1406 | if (state == NULL) | ||
1407 | return gs_error_VMerror; | ||
1408 | state->render = NULL; | ||
1409 | if (gx_default_transform_pixel_region(dev, transform_pixel_region_begin, data) < 0) { | ||
1410 | gs_free_object(dev->memory->non_gc_memory, state, "mem_transform_pixel_region_state_t"); | ||
1411 | return gs_error_VMerror; | ||
1412 | } | ||
1413 | state->passthru = data->state; | ||
1414 | data->state = state; | ||
1415 | return 0; | ||
1416 | } | ||
1417 | } else if (state->render == NULL) { | ||
1418 | int ret; | ||
1419 | data->state = state->passthru; | ||
1420 | ret = gx_default_transform_pixel_region(dev, reason, data); | ||
1421 | data->state = state; | ||
1422 | if (reason == transform_pixel_region_end) { | ||
1423 | gs_free_object(dev->memory->non_gc_memory, state, "mem_transform_pixel_region_state_t"); | ||
1424 | data->state = NULL; | ||
1425 | } | ||
1426 | return ret; | ||
1427 | } | ||
1428 | |||
1429 | /* We can handle this case natively */ | ||
1430 | switch(reason) | ||
1431 | { | ||
1432 | case transform_pixel_region_begin: | ||
1433 | return mem_transform_pixel_region_begin(dev, data->u.init.w, data->u.init.h, data->u.init.spp, data->u.init.pixels, data->u.init.rows, data->u.init.clip, posture, (mem_transform_pixel_region_state_t **)&data->state); | ||
1434 | case transform_pixel_region_data_needed: | ||
1435 | return mem_transform_pixel_region_data_needed(dev, state); | ||
1436 | case transform_pixel_region_process_data: | ||
1437 | return mem_transform_pixel_region_process_data(dev, state, data->u.process_data.buffer, data->u.process_data.data_x, data->u.process_data.cmapper, data->u.process_data.pgs); | ||
1438 | case transform_pixel_region_end: | ||
1439 | data->state = NULL; | ||
1440 | return mem_transform_pixel_region_end(dev, state); | ||
1441 | default: | ||
1442 | return gs_error_unknownerror; | ||
1443 | } | ||
1444 | } | ||
diff --git a/base/gdevmem.h b/base/gdevmem.h index 262c9d109..15174571e 100644 --- a/base/gdevmem.h +++ b/base/gdevmem.h | |||
@@ -102,6 +102,7 @@ dev_proc_map_color_rgb(mem_mapped_map_color_rgb); | |||
102 | /* Default implementations */ | 102 | /* Default implementations */ |
103 | dev_proc_strip_copy_rop(mem_default_strip_copy_rop); | 103 | dev_proc_strip_copy_rop(mem_default_strip_copy_rop); |
104 | dev_proc_strip_copy_rop2(mem_default_strip_copy_rop2); | 104 | dev_proc_strip_copy_rop2(mem_default_strip_copy_rop2); |
105 | dev_proc_transform_pixel_region(mem_transform_pixel_region); | ||
105 | 106 | ||
106 | /* | 107 | /* |
107 | * Macro for generating the device descriptor. | 108 | * Macro for generating the device descriptor. |
@@ -182,7 +183,26 @@ dev_proc_strip_copy_rop2(mem_default_strip_copy_rop2); | |||
182 | NULL, /* encode_color */\ | 183 | NULL, /* encode_color */\ |
183 | NULL, /* decode_color */\ | 184 | NULL, /* decode_color */\ |
184 | NULL, /* pattern_manage */\ | 185 | NULL, /* pattern_manage */\ |
185 | fill_rectangle_hl_color /* fill_rectangle_hl_color */\ | 186 | fill_rectangle_hl_color, /* fill_rectangle_hl_color */\ |
187 | NULL, /* include_color_space */\ | ||
188 | NULL, /* fill_linear_color_scanline */\ | ||
189 | NULL, /* fill_linear_color_trapezoid */\ | ||
190 | NULL, /* fill_linear_color_triangle */\ | ||
191 | NULL, /* update_spot_equivalent_colors */\ | ||
192 | NULL, /* ret_devn_params */\ | ||
193 | NULL, /* fillpage */\ | ||
194 | NULL, /* push_transparency_state */\ | ||
195 | NULL, /* pop_transparency_state */\ | ||
196 | NULL, /* put_image */\ | ||
197 | NULL, /* dev_spec_op */\ | ||
198 | NULL, /* copy_planes */\ | ||
199 | NULL, /* get_profile */\ | ||
200 | NULL, /* set_graphics_type_tag */\ | ||
201 | NULL, /* strip_copy_rop2 */\ | ||
202 | NULL, /* strip_tile_rect_devn */\ | ||
203 | NULL, /* copy_alpha_hl_color */\ | ||
204 | NULL, /* process_page */\ | ||
205 | mem_transform_pixel_region\ | ||
186 | },\ | 206 | },\ |
187 | 0, /* target */\ | 207 | 0, /* target */\ |
188 | mem_device_init_private /* see gxdevmem.h */\ | 208 | mem_device_init_private /* see gxdevmem.h */\ |