📄 gdkcc.c
字号:
break; case GDK_VISUAL_TRUE_COLOR: /* shifts */ GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_new: visual class is GDK_VISUAL_TRUE_COLOR\n")); init_true_color (cc); break; case GDK_VISUAL_DIRECT_COLOR: /* shifts and fake CLUT */ GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_new: visual class is GDK_VISUAL_DIRECT_COLOR\n")); init_direct_color (cc); break; case GDK_VISUAL_STATIC_COLOR: case GDK_VISUAL_PSEUDO_COLOR: GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_new: visual class is %s\n", (visual->type == GDK_VISUAL_STATIC_COLOR) ? "GDK_VISUAL_STATIC_COLOR" : "GDK_VISUAL_PSEUDO_COLOR")); init_color (cc); break; default: g_assert_not_reached (); } if ((cc->mode == GDK_CC_MODE_BW) && (cc->visual->depth > 1)) { use_private_colormap = TRUE; retry_count++; } else break; } /* no. of colors allocated yet */ cc->num_allocated = 0; GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_new: screen depth is %i, no. of colors is %i\n", cc->visual->depth, cc->num_colors)); return (GdkColorContext *) cc;}GdkColorContext *gdk_color_context_new_mono (GdkVisual *visual, GdkColormap *colormap){ GdkColorContextPrivate *ccp; GdkColorContext *cc; g_assert (visual != NULL); g_assert (colormap != NULL); cc = g_new (GdkColorContext, 1); ccp = (GdkColorContextPrivate *) cc; ccp->xdisplay = gdk_display; cc->visual = visual; cc->colormap = colormap; cc->clut = NULL; cc->cmap = NULL; cc->mode = GDK_CC_MODE_UNDEFINED; cc->need_to_free_colormap = FALSE; init_bw (cc); return (GdkColorContext *) cc;}/* This doesn't currently free black/white, hmm... */voidgdk_color_context_free (GdkColorContext *cc){ g_assert (cc != NULL); if ((cc->visual->type == GDK_VISUAL_STATIC_COLOR) || (cc->visual->type == GDK_VISUAL_PSEUDO_COLOR)) { gdk_colors_free (cc->colormap, cc->clut, cc->num_allocated, 0); g_free (cc->clut); } else if (cc->clut != NULL) { gdk_colors_free (cc->colormap, cc->clut, cc->num_colors, 0); g_free (cc->clut); } if (cc->cmap != NULL) g_free (cc->cmap); if (cc->need_to_free_colormap) gdk_colormap_unref (cc->colormap); /* free any palette that has been associated with this GdkColorContext */ init_palette (cc); g_free (cc);}gulonggdk_color_context_get_pixel (GdkColorContext *cc, gushort red, gushort green, gushort blue, gint *failed){ GdkColorContextPrivate *ccp = (GdkColorContextPrivate *) cc; g_assert (cc != NULL); g_assert (failed != NULL); *failed = FALSE; switch (cc->mode) { case GDK_CC_MODE_BW: { gdouble value; value = (red / 65535.0 * 0.30 + green / 65535.0 * 0.59 + blue / 65535.0 * 0.11); if (value > 0.5) return cc->white_pixel; return cc->black_pixel; } case GDK_CC_MODE_MY_GRAY: { gulong ired, igreen, iblue; red = red * 0.30 + green * 0.59 + blue * 0.11; green = 0; blue = 0; if ((ired = red * (ccp->std_cmap.red_max + 1) / 0xffff) > ccp->std_cmap.red_max) ired = ccp->std_cmap.red_max; ired *= ccp->std_cmap.red_mult; if ((igreen = green * (ccp->std_cmap.green_max + 1) / 0xffff) > ccp->std_cmap.green_max) igreen = ccp->std_cmap.green_max; igreen *= ccp->std_cmap.green_mult; if ((iblue = blue * (ccp->std_cmap.blue_max + 1) / 0xffff) > ccp->std_cmap.blue_max) iblue = ccp->std_cmap.blue_max; iblue *= ccp->std_cmap.blue_mult; if (cc->clut != NULL) return cc->clut[ccp->std_cmap.base_pixel + ired + igreen + iblue]; return ccp->std_cmap.base_pixel + ired + igreen + iblue; } case GDK_CC_MODE_TRUE: { gulong ired, igreen, iblue; if (cc->clut == NULL) { red >>= 16 - cc->bits.red; green >>= 16 - cc->bits.green; blue >>= 16 - cc->bits.blue; ired = (red << cc->shifts.red) & cc->masks.red; igreen = (green << cc->shifts.green) & cc->masks.green; iblue = (blue << cc->shifts.blue) & cc->masks.blue; return ired | igreen | iblue; } ired = cc->clut[red * cc->max_entry / 65535] & cc->masks.red; igreen = cc->clut[green * cc->max_entry / 65535] & cc->masks.green; iblue = cc->clut[blue * cc->max_entry / 65535] & cc->masks.blue; return ired | igreen | iblue; } case GDK_CC_MODE_PALETTE: return gdk_color_context_get_pixel_from_palette (cc, &red, &green, &blue, failed); case GDK_CC_MODE_STD_CMAP: default: { GdkColor color; GdkColor *result = NULL; color.red = red; color.green = green; color.blue = blue; if (cc->color_hash) result = g_hash_table_lookup (cc->color_hash, &color); if (!result) { color.red = red; color.green = green; color.blue = blue; color.pixel = 0; if (!gdk_color_alloc (cc->colormap, &color)) *failed = TRUE; else { GdkColor *cnew; /* XXX: the following comment comes directly from * XCC.c. I don't know if it is relevant for * gdk_color_alloc() as it is for XAllocColor() * - Federico */ /* * I can't figure this out entirely, but it *is* possible * that XAllocColor succeeds, even if the number of * allocations we've made exceeds the number of available * colors in the current colormap. And therefore it * might be necessary for us to resize the CLUT. */ if (cc->num_allocated == cc->max_colors) { cc->max_colors *= 2; GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_get_pixel: " "resizing CLUT to %i entries\n", cc->max_colors)); cc->clut = g_realloc (cc->clut, cc->max_colors * sizeof (gulong)); } /* Key and value are the same color structure */ cnew = g_new (GdkColor, 1); *cnew = color; if (!cc->color_hash) cc->color_hash = g_hash_table_new (hash_color, compare_colors); g_hash_table_insert (cc->color_hash, cnew, cnew); cc->clut[cc->num_allocated] = color.pixel; cc->num_allocated++; return color.pixel; } } return result->pixel; } }}voidgdk_color_context_get_pixels (GdkColorContext *cc, gushort *reds, gushort *greens, gushort *blues, gint ncolors, gulong *colors, gint *nallocated){ gint i, k, idx; gint cmapsize, ncols = 0, nopen = 0, counter = 0; gint bad_alloc = FALSE; gint failed[MAX_IMAGE_COLORS], allocated[MAX_IMAGE_COLORS]; GdkColor defs[MAX_IMAGE_COLORS], cmap[MAX_IMAGE_COLORS];#ifdef G_ENABLE_DEBUG gint exact_col = 0, subst_col = 0, close_col = 0, black_col = 0;#endif g_assert (cc != NULL); g_assert (reds != NULL); g_assert (greens != NULL); g_assert (blues != NULL); g_assert (colors != NULL); g_assert (nallocated != NULL); memset (defs, 0, MAX_IMAGE_COLORS * sizeof (GdkColor)); memset (failed, 0, MAX_IMAGE_COLORS * sizeof (gint)); memset (allocated, 0, MAX_IMAGE_COLORS * sizeof (gint)); /* Will only have a value if used by the progressive image loader */ ncols = *nallocated; *nallocated = 0; /* First allocate all pixels */ for (i = 0; i < ncolors; i++) { /* colors[i] is only zero if the pixel at that location hasn't * been allocated yet. This is a sanity check required for proper * color allocation by the progressive image loader */ if (colors[i] == 0) { defs[i].red = reds[i]; defs[i].green = greens[i]; defs[i].blue = blues[i]; colors[i] = gdk_color_context_get_pixel (cc, reds[i], greens[i], blues[i], &bad_alloc); /* successfully allocated, store it */ if (!bad_alloc) { defs[i].pixel = colors[i]; allocated[ncols++] = colors[i]; } else failed[nopen++] = i; } } *nallocated = ncols; /* all colors available, all done */ if ((ncols == ncolors) || (nopen == 0)) { GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_get_pixels: got all %i colors; " "(%i colors allocated so far)\n", ncolors, cc->num_allocated)); return; } /* The fun part. We now try to allocate the colors we couldn't allocate * directly. The first step will map a color onto its nearest color * that has been allocated (either by us or someone else). If any colors * remain unallocated, we map these onto the colors that we have allocated * ourselves. */ /* read up to MAX_IMAGE_COLORS colors of the current colormap */ cmapsize = MIN (cc->num_colors, MAX_IMAGE_COLORS); /* see if the colormap has any colors to read */ if (cmapsize < 0) { g_warning ("gdk_color_context_get_pixels: oops! no colors available, " "your images will look *really* ugly."); return; } #ifdef G_ENABLE_DEBUG exact_col = ncols;#endif /* initialize pixels */ for (i = 0; i < cmapsize; i++) { cmap[i].pixel = i; cmap[i].red = cmap[i].green = cmap[i].blue = 0; } /* read the colormap */ my_x_query_colors (cc->colormap, cmap, cmapsize); /* get a close match for any unallocated colors */ counter = nopen; nopen = 0; idx = 0; do { gint d, j, mdist, close, ri, gi, bi; gint rd, gd, bd; i = failed[idx]; mdist = 0x1000000; close = -1; /* Store these vals. Small performance increase as this skips three * indexing operations in the loop code. */ ri = reds[i]; gi = greens[i]; bi = blues[i]; /* Walk all colors in the colormap and see which one is the * closest. Uses plain least squares. */ for (j = 0; (j < cmapsize) && (mdist != 0); j++) { /* Don't replace these by shifts; the sign may get clobbered */ rd = (ri - cmap[j].red) / 256; gd = (gi - cmap[j].green) / 256; bd = (bi - cmap[j].blue) / 256; d = rd * rd + gd * gd + bd * bd; if (d < mdist) { close = j; mdist = d; } } if (close != -1) { rd = cmap[close].red; gd = cmap[close].green; bd = cmap[close].blue; /* allocate */ colors[i] = gdk_color_context_get_pixel (cc, rd, gd, bd, &bad_alloc); /* store */ if (!bad_alloc) { defs[i] = cmap[close]; defs[i].pixel = colors[i]; allocated[ncols++] = colors[i];#ifdef G_ENABLE_DEBUG close_col++;#endif } else failed[nopen++] = i; } else failed[nopen++] = i; /* deal with in next stage if allocation failed */ } while (++idx < counter); *nallocated = ncols; /* This is the maximum no. of allocated colors. See also the nopen == 0 * note above. */ if ((ncols == ncolors) || (nopen == 0)) { GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_get_pixels: got %i colors, %i exact and " "%i close (%i colors allocated so far)\n", ncolors, exact_col, close_col, cc->num_allocated)); return; } /* Now map any remaining unallocated pixels into the colors we did get */ idx = 0; do { gint d, mdist, close, ri, gi, bi; gint j, rd, gd, bd; i = failed[idx]; mdist = 0x1000000; close = -1; /* store */ ri = reds[i]; gi = greens[i]; bi = blues[i]; /* search allocated colors */ for (j = 0; (j < ncols) && (mdist != 0); j++) { k = allocated[j]; /* Don't replace these by shifts; the sign may get clobbered */ rd = (ri - defs[k].red) / 256; gd = (gi - defs[k].green) / 256; bd = (bi - defs[k].blue) / 256; d = rd * rd + gd * gd + bd * bd; if (d < mdist) { close = k; mdist = d; } } if (close < 0) { /* too bad, map to black */ defs[i].pixel = cc->black_pixel; defs[i].red = defs[i].green = defs[i].blue = 0;#ifdef G_ENABLE_DEBUG black_col++;#endif } else { defs[i] = defs[close];#ifdef G_ENABLE_DEBUG subst_col++;#endif } colors[i] = defs[i].pixel; } while (++idx < nopen); GDK_NOTE (COLOR_CONTEXT, g_message ("gdk_color_context_get_pixels: got %i colors, %i exact, %i close, " "%i substituted, %i to black (%i colors allocated so far)\n", ncolors, exact_col, close_col, subst_col, black_col, cc->num_allocated));}voidgdk_color_context_get_pixels_incremental (GdkColorContext *cc, gushort *reds, gushort *greens, gushort *blues, gint ncolors, gint *used, gulong *colors, gint *nallocated){ gint i, k, idx; gint cmapsize, ncols = 0, nopen = 0, counter = 0; gint bad_alloc = FALSE; gint failed[MAX_IMAGE_COLORS], allocated[MAX_IMAGE_COLORS]; GdkColor defs[MAX_IMAGE_COLORS], cmap[MAX_IMAGE_COLORS];#ifdef G_ENABLE_DEBUG gint exact_col = 0, subst_col = 0, close_col = 0, black_col = 0;#endif g_assert (cc != NULL); g_assert (reds != NULL); g_assert (greens != NULL); g_assert (blues != NULL); g_assert (used != NULL); g_assert (colors != NULL); g_assert (nallocated != NULL); memset (defs, 0, MAX_IMAGE_COLORS * sizeof (GdkColor)); memset (failed, 0, MAX_IMAGE_COLORS * sizeof (gint)); memset (allocated, 0, MAX_IMAGE_COLORS * sizeof (gint)); /* Will only have a value if used by the progressive image loader */ ncols = *nallocated;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -