#include "HalftoneView.h" #include #include HalftonePreviewView::HalftonePreviewView(BRect frame, const char* name, uint32 resizeMask, uint32 flags) : BView(frame, name, resizeMask, flags) { } void HalftonePreviewView::Preview(float gamma, float min, Halftone::DitherType ditherType, bool color) { const color_space kColorSpace = B_RGB32; const float right = Bounds().Width(); const float bottom = Bounds().Height(); BRect rect(0, 0, right, bottom); BBitmap testImage(rect, kColorSpace, true); BBitmap preview(rect, kColorSpace); BView view(rect, "", B_FOLLOW_ALL, B_WILL_DRAW); // create test image testImage.Lock(); testImage.AddChild(&view); // color bars const int height = Bounds().IntegerHeight()+1; const int width = Bounds().IntegerWidth()+1; const int delta = height / 4; const float red_bottom = delta - 1; const float green_bottom = red_bottom + delta; const float blue_bottom = green_bottom + delta; const float gray_bottom = height - 1; for (int x = 0; x <= right; x ++) { uchar value = x * 255 / width; BPoint from(x, 0); BPoint to(x, red_bottom); // red view.SetHighColor(255, value, value); view.StrokeLine(from, to); // green from.y = to.y+1; to.y = green_bottom; view.SetHighColor(value, 255, value); view.StrokeLine(from, to); // blue from.y = to.y+1; to.y = blue_bottom; view.SetHighColor(value, value, 255); view.StrokeLine(from, to); // gray from.y = to.y+1; to.y = gray_bottom; view.SetHighColor(value, value, value); view.StrokeLine(from, to); } view.Sync(); testImage.RemoveChild(&view); testImage.Unlock(); // create preview image Halftone halftone(kColorSpace, gamma, min, ditherType); halftone.SetBlackValue(Halftone::kLowValueMeansBlack); const int widthBytes = (width + 7) / 8; // byte boundary uchar* buffer = new uchar[widthBytes]; const uchar* src = (uchar*)testImage.Bits(); uchar* dstRow = (uchar*)preview.Bits(); const int numPlanes = color ? 3 : 1; if (color) { halftone.SetPlanes(Halftone::kPlaneRGB1); } for (int y = 0; y < height; y ++) { for (int plane = 0; plane < numPlanes; plane ++) { // halftone the preview image halftone.Dither(buffer, src, 0, y, width); // convert the plane(s) to RGB32 ColorRGB32Little* dst = (ColorRGB32Little*)dstRow; const uchar* bitmap = buffer; for (int x = 0; x < width; x ++, dst ++) { const int bit = 7 - (x % 8); const bool isSet = (*bitmap & (1 << bit)) != 0; uchar value = isSet ? 255 : 0; if (color) { switch (plane) { case 0: dst->red = value; break; case 1: dst->green = value; break; case 2: dst->blue = value; break; } } else { dst->red = dst->green = dst->blue = value; } if (bit == 0) { bitmap ++; } } } // next row src += testImage.BytesPerRow(); dstRow += preview.BytesPerRow(); } delete[] buffer; SetViewBitmap(&preview); Invalidate(); } HalftoneView::HalftoneView(BRect frame, const char* name, uint32 resizeMask, uint32 flags) : BView(frame, name, resizeMask, flags) { SetViewUIColor(B_PANEL_BACKGROUND_COLOR); BRect r(frame); float size, max; r.OffsetTo(0, 0); const int height = r.IntegerHeight()+1; const int delta = height / 4; const float red_top = 0; const float green_top = delta; const float blue_top = green_top + delta; const float gray_top = r.bottom - delta; const char* kRedLabel = "Red: "; const char* kGreenLabel = "Green: "; const char* kBlueLabel = "Blue: "; const char* kGrayLabel = "Black: "; BFont font(be_plain_font); font_height fh; font.GetHeight(&fh); max = size = font.StringWidth(kRedLabel); r.Set(0, 0, size, fh.ascent + fh.descent); r.OffsetTo(0, red_top); r.right = r.left + size; AddChild(new BStringView(r, "red", kRedLabel)); size = font.StringWidth(kGreenLabel); r.Set(0, 0, size, fh.ascent + fh.descent); if (max < size) max = size; r.OffsetTo(0, green_top); r.right = r.left + size; AddChild(new BStringView(r, "green", kGreenLabel)); size = font.StringWidth(kBlueLabel); r.Set(0, 0, size, fh.ascent + fh.descent); if (max < size) max = size; r.OffsetTo(0, blue_top); r.right = r.left + size; AddChild(new BStringView(r, "blue", kBlueLabel)); size = font.StringWidth(kGrayLabel); r.Set(0, 0, size, fh.ascent + fh.descent); if (max < size) max = size; r.OffsetTo(0, gray_top); r.right = r.left + size; AddChild(new BStringView(r, "gray", kGrayLabel)); r = frame; r.OffsetTo(max, 0); r.right -= max; fPreview = new HalftonePreviewView(r, "preview", resizeMask, flags); AddChild(fPreview); } void HalftoneView::Preview(float gamma, float min, Halftone::DitherType ditherType, bool color) { fPreview->Preview(gamma, min, ditherType, color); }