void gfxPlatform::TransformPixel(const gfxRGBA& in, gfxRGBA& out, qcms_transform *transform) { if (transform) { /* we want the bytes in RGB order */ #ifdef IS_LITTLE_ENDIAN /* ABGR puts the bytes in |RGBA| order on little endian */ PRUint32 packed = in.Packed(gfxRGBA::PACKED_ABGR); qcms_transform_data(transform, (PRUint8 *)&packed, (PRUint8 *)&packed, 1); out.~gfxRGBA(); new (&out) gfxRGBA(packed, gfxRGBA::PACKED_ABGR); #else /* ARGB puts the bytes in |ARGB| order on big endian */ PRUint32 packed = in.Packed(gfxRGBA::PACKED_ARGB); /* add one to move past the alpha byte */ qcms_transform_data(transform, (PRUint8 *)&packed + 1, (PRUint8 *)&packed + 1, 1); out.~gfxRGBA(); new (&out) gfxRGBA(packed, gfxRGBA::PACKED_ARGB); #endif } else if (&out != &in) out = in; }
template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, ImageFrame& buffer) { JSAMPARRAY samples = reader->samples(); jpeg_decompress_struct* info = reader->info(); int width = info->output_width; while (info->output_scanline < info->output_height) { // jpeg_read_scanlines will increase the scanline counter, so we // save the scanline before calling it. int y = info->output_scanline; // Request one scanline: returns 0 or 1 scanlines. if (jpeg_read_scanlines(info, samples, 1) != 1) return false; #if USE(QCMSLIB) if (reader->colorTransform() && colorSpace == JCS_RGB) qcms_transform_data(reader->colorTransform(), *samples, *samples, width); #endif ImageFrame::PixelData* pixel = buffer.getAddr(0, y); for (int x = 0; x < width; ++pixel, ++x) setPixel<colorSpace>(buffer, pixel, samples, x); } buffer.setPixelsChanged(true); return true; }
bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) { JSAMPARRAY samples = m_reader->samples(); jpeg_decompress_struct* info = m_reader->info(); int width = isScaled ? m_scaledColumns.size() : info->output_width; while (info->output_scanline < info->output_height) { // jpeg_read_scanlines will increase the scanline counter, so we // save the scanline before calling it. int sourceY = info->output_scanline; /* Request one scanline. Returns 0 or 1 scanlines. */ if (jpeg_read_scanlines(info, samples, 1) != 1) return false; int destY = scaledY(sourceY); if (destY < 0) continue; #if USE(QCMSLIB) if (m_reader->colorTransform() && colorSpace == JCS_RGB) qcms_transform_data(m_reader->colorTransform(), *samples, *samples, info->output_width); #endif ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY); for (int x = 0; x < width; ++x) { setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x); ++currentAddress; } } return true; }
// ----------------------------------------------------------------------------- // Color profile handling static int ApplyColorProfile(const WebPData* const profile, WebPDecBuffer* const rgba) { #ifdef WEBP_HAVE_QCMS int i, ok = 0; uint8_t* line; uint8_t major_revision; qcms_profile* input_profile = NULL; qcms_profile* output_profile = NULL; qcms_transform* transform = NULL; const qcms_data_type input_type = QCMS_DATA_RGBA_8; const qcms_data_type output_type = QCMS_DATA_RGBA_8; const qcms_intent intent = QCMS_INTENT_DEFAULT; if (profile == NULL || rgba == NULL) return 0; if (profile->bytes == NULL || profile->size < 10) return 1; major_revision = profile->bytes[8]; qcms_enable_iccv4(); input_profile = qcms_profile_from_memory(profile->bytes, profile->size); // qcms_profile_is_bogus() is broken with ICCv4. if (input_profile == NULL || (major_revision < 4 && qcms_profile_is_bogus(input_profile))) { fprintf(stderr, "Color profile is bogus!\n"); goto Error; } output_profile = qcms_profile_sRGB(); if (output_profile == NULL) { fprintf(stderr, "Error creating output color profile!\n"); goto Error; } qcms_profile_precache_output_transform(output_profile); transform = qcms_transform_create(input_profile, input_type, output_profile, output_type, intent); if (transform == NULL) { fprintf(stderr, "Error creating color transform!\n"); goto Error; } line = rgba->u.RGBA.rgba; for (i = 0; i < rgba->height; ++i, line += rgba->u.RGBA.stride) { qcms_transform_data(transform, line, line, rgba->width); } ok = 1; Error: if (input_profile != NULL) qcms_profile_release(input_profile); if (output_profile != NULL) qcms_profile_release(output_profile); if (transform != NULL) qcms_transform_release(transform); return ok; #else (void)profile; (void)rgba; return 1; #endif // WEBP_HAVE_QCMS }
static void transform(qcms_profile* src_profile, qcms_profile* dst_profile, size_t size) { // qcms supports GRAY and RGB profiles as input, and RGB as output. uint32_t src_color_space = qcms_profile_get_color_space(src_profile); qcms_data_type src_type = size & 1 ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; if (src_color_space == icSigGrayData) { src_type = size & 1 ? QCMS_DATA_GRAYA_8 : QCMS_DATA_GRAY_8; } else if (src_color_space != icSigRgbData) { return; } uint32_t dst_color_space = qcms_profile_get_color_space(dst_profile); if (dst_color_space != icSigRgbData) { return; } qcms_data_type dst_type = size & 2 ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8; qcms_intent intent = qcms_profile_get_rendering_intent(src_profile); // Firefox calls this on the display profile to increase performance. // Skip with low probability to increase coverage. if (size % 15) { qcms_profile_precache_output_transform(dst_profile); } qcms_transform* transform = qcms_transform_create(src_profile, src_type, dst_profile, dst_type, intent); if (!transform) { return; } static uint8_t src[] = { 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0x7F, 0x10, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xBF, 0xEF, 0x6F, 0x3F, 0xC0, 0x9F, 0xE0, 0x90, 0xCF, 0x40, 0xAF, 0x0F, 0x01, 0x60, 0xF0, }; static uint8_t dst[sizeof(src) * 4]; // 4x in case of GRAY to RGBA int src_bytes_per_pixel = 4; // QCMS_DATA_RGBA_8 if (src_type == QCMS_DATA_RGB_8) { src_bytes_per_pixel = 3; } else if (src_type == QCMS_DATA_GRAYA_8) { src_bytes_per_pixel = 2; } else if (src_type == QCMS_DATA_GRAY_8) { src_bytes_per_pixel = 1; } qcms_transform_data(transform, src, dst, sizeof(src) / src_bytes_per_pixel); qcms_transform_release(transform); }
void test_gray(qcms_profile *output_profile) { unsigned char srct[3] = { 221, 79, 129}; unsigned char outt[3]; qcms_transform *transform; qcms_profile *gray_profile = qcms_profile_from_memory(gray_icc, sizeof(gray_icc)); if (gray_profile) { transform = qcms_transform_create(gray_profile, QCMS_DATA_GRAY_8, output_profile, QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL); if (transform) { qcms_transform_data(transform, srct, outt, 1); qcms_transform_release(transform); } qcms_profile_release(gray_profile); } }
/// Expand the colormap from RGB to Packed ARGB as needed by Cairo. /// And apply any LCMS transformation. static void ConvertColormap(uint32_t* aColormap, uint32_t aColors) { // Apply CMS transformation if enabled and available if (gfxPlatform::GetCMSMode() == eCMSMode_All) { qcms_transform* transform = gfxPlatform::GetCMSRGBTransform(); if (transform) { qcms_transform_data(transform, aColormap, aColormap, aColors); } } // Convert from the GIF's RGB format to the Cairo format. // Work from end to begin, because of the in-place expansion uint8_t* from = ((uint8_t*)aColormap) + 3 * aColors; uint32_t* to = aColormap + aColors; // Convert color entries to Cairo format // set up for loops below if (!aColors) { return; } uint32_t c = aColors; // copy as bytes until source pointer is 32-bit-aligned // NB: can't use 32-bit reads, they might read off the end of the buffer for (; (NS_PTR_TO_UINT32(from) & 0x3) && c; --c) { from -= 3; *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]); } // bulk copy of pixels. while (c >= 4) { from -= 12; to -= 4; c -= 4; GFX_BLOCK_RGB_TO_FRGB(from,to); } // copy remaining pixel(s) // NB: can't use 32-bit reads, they might read off the end of the buffer while (c--) { from -= 3; *--to = gfxPackedPixel(0xFF, from[0], from[1], from[2]); } }
void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int) { if (m_frameBufferCache.isEmpty()) return; // Initialize the framebuffer if needed. ImageFrame& buffer = m_frameBufferCache[0]; if (buffer.status() == ImageFrame::FrameEmpty) { png_structp png = m_reader->pngPtr(); if (!buffer.setSize(size().width(), size().height())) { longjmp(JMPBUF(png), 1); return; } unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr())) { m_reader->createInterlaceBuffer(colorChannels * size().width() * size().height()); if (!m_reader->interlaceBuffer()) { longjmp(JMPBUF(png), 1); return; } } #if USE(QCMSLIB) if (m_reader->colorTransform()) { m_reader->createRowBuffer(colorChannels * size().width()); if (!m_reader->rowBuffer()) { longjmp(JMPBUF(png), 1); return; } } #endif buffer.setStatus(ImageFrame::FramePartial); buffer.setHasAlpha(false); // For PNGs, the frame always fills the entire image. buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); } /* libpng comments (here to explain what follows). * * this function is called for every row in the image. If the * image is interlacing, and you turned on the interlace handler, * this function will be called for every row in every pass. * Some of these rows will not be changed from the previous pass. * When the row is not changed, the new_row variable will be NULL. * The rows and passes are called in order, so you don't really * need the row_num and pass, but I'm supplying them because it * may make your life easier. */ // Nothing to do if the row is unchanged, or the row is outside // the image bounds: libpng may send extra rows, ignore them to // make our lives easier. if (!rowBuffer) return; int y = rowIndex; if (y < 0 || y >= size().height()) return; /* libpng comments (continued). * * For the non-NULL rows of interlaced images, you must call * png_progressive_combine_row() passing in the row and the * old row. You can call this function for NULL rows (it will * just return) and for non-interlaced images (it just does the * memcpy for you) if it will make the code easier. Thus, you * can just do this for all cases: * * png_progressive_combine_row(png_ptr, old_row, new_row); * * where old_row is what was displayed for previous rows. Note * that the first pass (pass == 0 really) will completely cover * the old row, so the rows do not have to be initialized. After * the first pass (and only for interlaced images), you will have * to pass the current row, and the function will combine the * old row and the new row. */ bool hasAlpha = m_reader->hasAlpha(); png_bytep row = rowBuffer; if (png_bytep interlaceBuffer = m_reader->interlaceBuffer()) { unsigned colorChannels = hasAlpha ? 4 : 3; row = interlaceBuffer + (rowIndex * colorChannels * size().width()); png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer); } #if USE(QCMSLIB) if (qcms_transform* transform = m_reader->colorTransform()) { qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width()); row = m_reader->rowBuffer(); } #endif // Write the decoded row pixels to the frame buffer. The repetitive // form of the row write loops is for speed. ImageFrame::PixelData* address = buffer.getAddr(0, y); unsigned alphaMask = 255; int width = size().width(); png_bytep pixel = row; if (hasAlpha) { if (buffer.premultiplyAlpha()) { for (int x = 0; x < width; ++x, pixel += 4) { buffer.setRGBAPremultiply(address++, pixel[0], pixel[1], pixel[2], pixel[3]); alphaMask &= pixel[3]; } } else { for (int x = 0; x < width; ++x, pixel += 4) { buffer.setRGBARaw(address++, pixel[0], pixel[1], pixel[2], pixel[3]); alphaMask &= pixel[3]; } } } else { for (int x = 0; x < width; ++x, pixel += 3) { buffer.setRGBARaw(address++, pixel[0], pixel[1], pixel[2], 255); } } if (alphaMask != 255 && !buffer.hasAlpha()) buffer.setHasAlpha(true); buffer.setPixelsChanged(true); }
void nsJPEGDecoder::OutputScanlines(bool* suspend) { *suspend = false; const uint32_t top = mInfo.output_scanline; while ((mInfo.output_scanline < mInfo.output_height)) { // Use the Cairo image buffer as scanline buffer uint32_t* imageRow = ((uint32_t*)mImageData) + (mInfo.output_scanline * mInfo.output_width); if (mInfo.out_color_space == MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB) { // Special case: scanline will be directly converted into packed ARGB if (jpeg_read_scanlines(&mInfo, (JSAMPARRAY)&imageRow, 1) != 1) { *suspend = true; // suspend break; } continue; // all done for this row! } JSAMPROW sampleRow = (JSAMPROW)imageRow; if (mInfo.output_components == 3) { // Put the pixels at end of row to enable in-place expansion sampleRow += mInfo.output_width; } // Request one scanline. Returns 0 or 1 scanlines. if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) { *suspend = true; // suspend break; } if (mTransform) { JSAMPROW source = sampleRow; if (mInfo.out_color_space == JCS_GRAYSCALE) { // Convert from the 1byte grey pixels at begin of row // to the 3byte RGB byte pixels at 'end' of row sampleRow += mInfo.output_width; } qcms_transform_data(mTransform, source, sampleRow, mInfo.output_width); // Move 3byte RGB data to end of row if (mInfo.out_color_space == JCS_CMYK) { memmove(sampleRow + mInfo.output_width, sampleRow, 3 * mInfo.output_width); sampleRow += mInfo.output_width; } } else { if (mInfo.out_color_space == JCS_CMYK) { // Convert from CMYK to RGB // We cannot convert directly to Cairo, as the CMSRGBTransform // may wants to do a RGB transform... // Would be better to have platform CMSenabled transformation // from CMYK to (A)RGB... cmyk_convert_rgb((JSAMPROW)imageRow, mInfo.output_width); sampleRow += mInfo.output_width; } if (mCMSMode == eCMSMode_All) { // No embedded ICC profile - treat as sRGB qcms_transform* transform = gfxPlatform::GetCMSRGBTransform(); if (transform) { qcms_transform_data(transform, sampleRow, sampleRow, mInfo.output_width); } } } // counter for while() loops below uint32_t idx = mInfo.output_width; // copy as bytes until source pointer is 32-bit-aligned for (; (NS_PTR_TO_UINT32(sampleRow) & 0x3) && idx; --idx) { *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]); sampleRow += 3; } // copy pixels in blocks of 4 while (idx >= 4) { GFX_BLOCK_RGB_TO_FRGB(sampleRow, imageRow); idx -= 4; sampleRow += 12; imageRow += 4; } // copy remaining pixel(s) while (idx--) { // 32-bit read of final pixel will exceed buffer, so read bytes *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1], sampleRow[2]); sampleRow += 3; } } if (top != mInfo.output_scanline) { nsIntRect r(0, top, mInfo.output_width, mInfo.output_scanline-top); PostInvalidation(r); } }
void nsPNGDecoder::row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { /* libpng comments: * * this function is called for every row in the image. If the * image is interlacing, and you turned on the interlace handler, * this function will be called for every row in every pass. * Some of these rows will not be changed from the previous pass. * When the row is not changed, the new_row variable will be * nullptr. The rows and passes are called in order, so you don't * really need the row_num and pass, but I'm supplying them * because it may make your life easier. * * For the non-nullptr rows of interlaced images, you must call * png_progressive_combine_row() passing in the row and the * old row. You can call this function for nullptr rows (it will * just return) and for non-interlaced images (it just does the * memcpy for you) if it will make the code easier. Thus, you * can just do this for all cases: * * png_progressive_combine_row(png_ptr, old_row, new_row); * * where old_row is what was displayed for previous rows. Note * that the first pass (pass == 0 really) will completely cover * the old row, so the rows do not have to be initialized. After * the first pass (and only for interlaced images), you will have * to pass the current row, and the function will combine the * old row and the new row. */ nsPNGDecoder* decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr)); // skip this frame if (decoder->mFrameIsHidden) { return; } if (row_num >= (png_uint_32) decoder->mFrameRect.height) { return; } if (new_row) { int32_t width = decoder->mFrameRect.width; uint32_t iwidth = decoder->mFrameRect.width; png_bytep line = new_row; if (decoder->interlacebuf) { line = decoder->interlacebuf + (row_num * decoder->mChannels * width); png_progressive_combine_row(png_ptr, line, new_row); } uint32_t bpr = width * sizeof(uint32_t); uint32_t* cptr32 = (uint32_t*)(decoder->mImageData + (row_num*bpr)); if (decoder->mTransform) { if (decoder->mCMSLine) { qcms_transform_data(decoder->mTransform, line, decoder->mCMSLine, iwidth); // copy alpha over uint32_t channels = decoder->mChannels; if (channels == 2 || channels == 4) { for (uint32_t i = 0; i < iwidth; i++) decoder->mCMSLine[4 * i + 3] = line[channels * i + channels - 1]; } line = decoder->mCMSLine; } else { qcms_transform_data(decoder->mTransform, line, line, iwidth); } } switch (decoder->format) { case gfx::SurfaceFormat::B8G8R8X8: { // counter for while() loops below uint32_t idx = iwidth; // copy as bytes until source pointer is 32-bit-aligned for (; (NS_PTR_TO_UINT32(line) & 0x3) && idx; --idx) { *cptr32++ = gfxPackedPixel(0xFF, line[0], line[1], line[2]); line += 3; } // copy pixels in blocks of 4 while (idx >= 4) { GFX_BLOCK_RGB_TO_FRGB(line, cptr32); idx -= 4; line += 12; cptr32 += 4; } // copy remaining pixel(s) while (idx--) { // 32-bit read of final pixel will exceed buffer, so read bytes *cptr32++ = gfxPackedPixel(0xFF, line[0], line[1], line[2]); line += 3; } } break; case gfx::SurfaceFormat::B8G8R8A8: { if (!decoder->mDisablePremultipliedAlpha) { for (uint32_t x=width; x>0; --x) { *cptr32++ = gfxPackedPixel(line[3], line[0], line[1], line[2]); line += 4; } } else { for (uint32_t x=width; x>0; --x) { *cptr32++ = gfxPackedPixelNoPreMultiply(line[3], line[0], line[1], line[2]); line += 4; } } } break; default: png_longjmp(decoder->mPNG, 1); } if (decoder->mNumFrames <= 1) { // Only do incremental image display for the first frame // XXXbholley - this check should be handled in the superclass nsIntRect r(0, row_num, width, 1); decoder->PostInvalidation(r); } } }
bool JPEGImageDecoder::outputScanlines() { if (m_frameBufferCache.isEmpty()) return false; // Initialize the framebuffer if needed. ImageFrame& buffer = m_frameBufferCache[0]; if (buffer.status() == ImageFrame::FrameEmpty) { if (!buffer.setSize(scaledSize().width(), scaledSize().height())) return setFailed(); buffer.setStatus(ImageFrame::FramePartial); // The buffer is transparent outside the decoded area while the image is // loading. The completed image will be marked fully opaque in jpegComplete(). buffer.setHasAlpha(true); buffer.setColorProfile(m_colorProfile); // For JPEGs, the frame always fills the entire image. buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); } jpeg_decompress_struct* info = m_reader->info(); #if !ENABLE(IMAGE_DECODER_DOWN_SAMPLING) && defined(TURBO_JPEG_RGB_SWIZZLE) if (turboSwizzled(info->out_color_space)) { ASSERT(!m_scaled); while (info->output_scanline < info->output_height) { unsigned char* row = reinterpret_cast<unsigned char*>(buffer.getAddr(0, info->output_scanline)); if (jpeg_read_scanlines(info, &row, 1) != 1) return false; #if USE(QCMSLIB) if (qcms_transform* transform = m_reader->colorTransform()) qcms_transform_data_type(transform, row, row, info->output_width, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); #endif } return true; } #endif JSAMPARRAY samples = m_reader->samples(); while (info->output_scanline < info->output_height) { // jpeg_read_scanlines will increase the scanline counter, so we // save the scanline before calling it. int sourceY = info->output_scanline; /* Request one scanline. Returns 0 or 1 scanlines. */ if (jpeg_read_scanlines(info, samples, 1) != 1) return false; int destY = scaledY(sourceY); if (destY < 0) continue; #if USE(QCMSLIB) if (m_reader->colorTransform() && info->out_color_space == JCS_RGB) qcms_transform_data(m_reader->colorTransform(), *samples, *samples, info->output_width); #endif int width = m_scaled ? m_scaledColumns.size() : info->output_width; for (int x = 0; x < width; ++x) { JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4); if (info->out_color_space == JCS_RGB) buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); #if defined(TURBO_JPEG_RGB_SWIZZLE) else if (info->out_color_space == JCS_EXT_RGBA) buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); else if (info->out_color_space == JCS_EXT_BGRA) buffer.setRGBA(x, destY, jsample[2], jsample[1], jsample[0], 0xFF); #endif else if (info->out_color_space == JCS_CMYK) { // Source is 'Inverted CMYK', output is RGB. // See: http://www.easyrgb.com/math.php?MATH=M12#text12 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb // From CMYK to CMY: // X = X * (1 - K ) + K [for X = C, M, or Y] // Thus, from Inverted CMYK to CMY is: // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK // From CMY (0..1) to RGB (0..1): // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] unsigned k = jsample[3]; buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF); } else { ASSERT_NOT_REACHED(); return setFailed(); } } } return true; }
// // All these routines will return NS_OK if they have a value, // in which case the nsLookAndFeel should use that value; // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the // platform-specific nsLookAndFeel should use its own values instead. // NS_IMETHODIMP nsXPLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor) { if (!sInitialized) Init(); // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color // use in a skin that uses them. When set, it will make all system // color pairs that are appropriate for foreground/background // pairing the same. This means if the skin is using system colors // correctly you will not be able to see *any* text. #undef DEBUG_SYSTEM_COLOR_USE #ifdef DEBUG_SYSTEM_COLOR_USE { nsresult rv = NS_OK; switch (aID) { // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors case eColor_activecaption: // active window caption background case eColor_captiontext: // text in active window caption aColor = NS_RGB(0xff, 0x00, 0x00); break; case eColor_highlight: // background of selected item case eColor_highlighttext: // text of selected item aColor = NS_RGB(0xff, 0xff, 0x00); break; case eColor_inactivecaption: // inactive window caption case eColor_inactivecaptiontext: // text in inactive window caption aColor = NS_RGB(0x66, 0x66, 0x00); break; case eColor_infobackground: // tooltip background color case eColor_infotext: // tooltip text color aColor = NS_RGB(0x00, 0xff, 0x00); break; case eColor_menu: // menu background case eColor_menutext: // menu text aColor = NS_RGB(0x00, 0xff, 0xff); break; case eColor_threedface: case eColor_buttonface: // 3-D face color case eColor_buttontext: // text on push buttons aColor = NS_RGB(0x00, 0x66, 0x66); break; case eColor_window: case eColor_windowtext: aColor = NS_RGB(0x00, 0x00, 0xff); break; // from the CSS3 working draft (not yet finalized) // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color case eColor__moz_field: case eColor__moz_fieldtext: aColor = NS_RGB(0xff, 0x00, 0xff); break; case eColor__moz_dialog: case eColor__moz_dialogtext: aColor = NS_RGB(0x66, 0x00, 0x66); break; default: rv = NS_ERROR_NOT_AVAILABLE; } if (NS_SUCCEEDED(rv)) return rv; } #endif // DEBUG_SYSTEM_COLOR_USE if (IS_COLOR_CACHED(aID)) { aColor = sCachedColors[aID]; return NS_OK; } // There are no system color settings for these, so set them manually if (aID == eColor_TextSelectBackgroundDisabled) { // This is used to gray out the selection when it's not focused // Used with nsISelectionController::SELECTION_DISABLED aColor = NS_RGB(0xb0, 0xb0, 0xb0); return NS_OK; } if (aID == eColor_TextSelectBackgroundAttention) { // This makes the selection stand out when typeaheadfind is on // Used with nsISelectionController::SELECTION_ATTENTION aColor = NS_RGB(0x38, 0xd8, 0x78); return NS_OK; } if (aID == eColor_TextHighlightBackground) { // This makes the matched text stand out when findbar highlighting is on // Used with nsISelectionController::SELECTION_FIND aColor = NS_RGB(0xef, 0x0f, 0xff); return NS_OK; } if (aID == eColor_TextHighlightForeground) { // The foreground color for the matched text in findbar highlighting // Used with nsISelectionController::SELECTION_FIND aColor = NS_RGB(0xff, 0xff, 0xff); return NS_OK; } if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aColor))) { if ((gfxPlatform::GetCMSMode() == eCMSMode_All) && !IsSpecialColor(aID, aColor)) { qcms_transform *transform = gfxPlatform::GetCMSInverseRGBTransform(); if (transform) { PRUint8 color[3]; color[0] = NS_GET_R(aColor); color[1] = NS_GET_G(aColor); color[2] = NS_GET_B(aColor); qcms_transform_data(transform, color, color, 1); aColor = NS_RGB(color[0], color[1], color[2]); } } CACHE_COLOR(aID, aColor); return NS_OK; } return NS_ERROR_NOT_AVAILABLE; }