112fd6cc2SKarsten Heimrich #include "HalftoneView.h" 212fd6cc2SKarsten Heimrich 312fd6cc2SKarsten Heimrich #include <Bitmap.h> 412fd6cc2SKarsten Heimrich #include <StringView.h> 512fd6cc2SKarsten Heimrich 6*4410ee12SMichael Pfeiffer 7*4410ee12SMichael Pfeiffer HalftonePreviewView::HalftonePreviewView(BRect frame, const char* name, 8*4410ee12SMichael Pfeiffer uint32 resizeMask, uint32 flags) 9*4410ee12SMichael Pfeiffer : 10*4410ee12SMichael Pfeiffer BView(frame, name, resizeMask, flags) 1112fd6cc2SKarsten Heimrich { 1212fd6cc2SKarsten Heimrich } 1312fd6cc2SKarsten Heimrich 14*4410ee12SMichael Pfeiffer 15*4410ee12SMichael Pfeiffer void 16*4410ee12SMichael Pfeiffer HalftonePreviewView::Preview(float gamma, float min, 17*4410ee12SMichael Pfeiffer Halftone::DitherType ditherType, bool color) 1812fd6cc2SKarsten Heimrich { 1912fd6cc2SKarsten Heimrich const color_space kColorSpace = B_RGB32; 2012fd6cc2SKarsten Heimrich const float right = Bounds().Width(); 2112fd6cc2SKarsten Heimrich const float bottom = Bounds().Height(); 2212fd6cc2SKarsten Heimrich BRect rect(0, 0, right, bottom); 2312fd6cc2SKarsten Heimrich 2412fd6cc2SKarsten Heimrich BBitmap testImage(rect, kColorSpace, true); 2512fd6cc2SKarsten Heimrich BBitmap preview(rect, kColorSpace); 2612fd6cc2SKarsten Heimrich BView view(rect, "", B_FOLLOW_ALL, B_WILL_DRAW); 2712fd6cc2SKarsten Heimrich 2812fd6cc2SKarsten Heimrich // create test image 2912fd6cc2SKarsten Heimrich testImage.Lock(); 3012fd6cc2SKarsten Heimrich testImage.AddChild(&view); 3112fd6cc2SKarsten Heimrich 3212fd6cc2SKarsten Heimrich // color bars 3312fd6cc2SKarsten Heimrich const int height = Bounds().IntegerHeight()+1; 3412fd6cc2SKarsten Heimrich const int width = Bounds().IntegerWidth()+1; 3512fd6cc2SKarsten Heimrich const int delta = height / 4; 3612fd6cc2SKarsten Heimrich const float red_bottom = delta - 1; 3712fd6cc2SKarsten Heimrich const float green_bottom = red_bottom + delta; 3812fd6cc2SKarsten Heimrich const float blue_bottom = green_bottom + delta; 3912fd6cc2SKarsten Heimrich const float gray_bottom = height - 1; 4012fd6cc2SKarsten Heimrich 4112fd6cc2SKarsten Heimrich for (int x = 0; x <= right; x ++) { 4212fd6cc2SKarsten Heimrich uchar value = x * 255 / width; 4312fd6cc2SKarsten Heimrich 4412fd6cc2SKarsten Heimrich BPoint from(x, 0); 4512fd6cc2SKarsten Heimrich BPoint to(x, red_bottom); 4612fd6cc2SKarsten Heimrich // red 4712fd6cc2SKarsten Heimrich view.SetHighColor(255, value, value); 4812fd6cc2SKarsten Heimrich view.StrokeLine(from, to); 4912fd6cc2SKarsten Heimrich // green 5012fd6cc2SKarsten Heimrich from.y = to.y+1; 5112fd6cc2SKarsten Heimrich to.y = green_bottom; 5212fd6cc2SKarsten Heimrich view.SetHighColor(value, 255, value); 5312fd6cc2SKarsten Heimrich view.StrokeLine(from, to); 5412fd6cc2SKarsten Heimrich // blue 5512fd6cc2SKarsten Heimrich from.y = to.y+1; 5612fd6cc2SKarsten Heimrich to.y = blue_bottom; 5712fd6cc2SKarsten Heimrich view.SetHighColor(value, value, 255); 5812fd6cc2SKarsten Heimrich view.StrokeLine(from, to); 5912fd6cc2SKarsten Heimrich // gray 6012fd6cc2SKarsten Heimrich from.y = to.y+1; 6112fd6cc2SKarsten Heimrich to.y = gray_bottom; 6212fd6cc2SKarsten Heimrich view.SetHighColor(value, value, value); 6312fd6cc2SKarsten Heimrich view.StrokeLine(from, to); 6412fd6cc2SKarsten Heimrich } 6512fd6cc2SKarsten Heimrich 6612fd6cc2SKarsten Heimrich view.Sync(); 6712fd6cc2SKarsten Heimrich testImage.RemoveChild(&view); 6812fd6cc2SKarsten Heimrich testImage.Unlock(); 6912fd6cc2SKarsten Heimrich 7012fd6cc2SKarsten Heimrich // create preview image 7112fd6cc2SKarsten Heimrich Halftone halftone(kColorSpace, gamma, min, ditherType); 72*4410ee12SMichael Pfeiffer halftone.SetBlackValue(Halftone::kLowValueMeansBlack); 7312fd6cc2SKarsten Heimrich 7412fd6cc2SKarsten Heimrich const int widthBytes = (width + 7) / 8; // byte boundary 7512fd6cc2SKarsten Heimrich uchar* buffer = new uchar[widthBytes]; 7612fd6cc2SKarsten Heimrich 7712fd6cc2SKarsten Heimrich const uchar* src = (uchar*)testImage.Bits(); 7812fd6cc2SKarsten Heimrich uchar* dstRow = (uchar*)preview.Bits(); 7912fd6cc2SKarsten Heimrich 8012fd6cc2SKarsten Heimrich const int numPlanes = color ? 3 : 1; 8112fd6cc2SKarsten Heimrich if (color) { 82*4410ee12SMichael Pfeiffer halftone.SetPlanes(Halftone::kPlaneRGB1); 8312fd6cc2SKarsten Heimrich } 8412fd6cc2SKarsten Heimrich 8512fd6cc2SKarsten Heimrich for (int y = 0; y < height; y ++) { 8612fd6cc2SKarsten Heimrich for (int plane = 0; plane < numPlanes; plane ++) { 8712fd6cc2SKarsten Heimrich // halftone the preview image 88*4410ee12SMichael Pfeiffer halftone.Dither(buffer, src, 0, y, width); 8912fd6cc2SKarsten Heimrich 9012fd6cc2SKarsten Heimrich // convert the plane(s) to RGB32 9112fd6cc2SKarsten Heimrich ColorRGB32Little* dst = (ColorRGB32Little*)dstRow; 9212fd6cc2SKarsten Heimrich const uchar* bitmap = buffer; 9312fd6cc2SKarsten Heimrich for (int x = 0; x < width; x ++, dst ++) { 9412fd6cc2SKarsten Heimrich const int bit = 7 - (x % 8); 9512fd6cc2SKarsten Heimrich const bool isSet = (*bitmap & (1 << bit)) != 0; 9612fd6cc2SKarsten Heimrich uchar value = isSet ? 255 : 0; 9712fd6cc2SKarsten Heimrich 9812fd6cc2SKarsten Heimrich if (color) { 9912fd6cc2SKarsten Heimrich switch (plane) { 10012fd6cc2SKarsten Heimrich case 0: dst->red = value; 10112fd6cc2SKarsten Heimrich break; 10212fd6cc2SKarsten Heimrich case 1: dst->green = value; 10312fd6cc2SKarsten Heimrich break; 10412fd6cc2SKarsten Heimrich case 2: dst->blue = value; 10512fd6cc2SKarsten Heimrich break; 10612fd6cc2SKarsten Heimrich } 10712fd6cc2SKarsten Heimrich } else { 10812fd6cc2SKarsten Heimrich dst->red = dst->green = dst->blue = value; 10912fd6cc2SKarsten Heimrich } 11012fd6cc2SKarsten Heimrich 11112fd6cc2SKarsten Heimrich if (bit == 0) { 11212fd6cc2SKarsten Heimrich bitmap ++; 11312fd6cc2SKarsten Heimrich } 11412fd6cc2SKarsten Heimrich } 11512fd6cc2SKarsten Heimrich } 11612fd6cc2SKarsten Heimrich 11712fd6cc2SKarsten Heimrich // next row 11812fd6cc2SKarsten Heimrich src += testImage.BytesPerRow(); 11912fd6cc2SKarsten Heimrich dstRow += preview.BytesPerRow(); 12012fd6cc2SKarsten Heimrich } 12112fd6cc2SKarsten Heimrich 122c9e62886SStefano Ceccherini delete[] buffer; 12312fd6cc2SKarsten Heimrich 12412fd6cc2SKarsten Heimrich SetViewBitmap(&preview); 12512fd6cc2SKarsten Heimrich Invalidate(); 12612fd6cc2SKarsten Heimrich } 12712fd6cc2SKarsten Heimrich 128*4410ee12SMichael Pfeiffer 129*4410ee12SMichael Pfeiffer HalftoneView::HalftoneView(BRect frame, const char* name, uint32 resizeMask, 13012fd6cc2SKarsten Heimrich uint32 flags) 131*4410ee12SMichael Pfeiffer : 132*4410ee12SMichael Pfeiffer BView(frame, name, resizeMask, flags) 13312fd6cc2SKarsten Heimrich { 13412fd6cc2SKarsten Heimrich SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 13512fd6cc2SKarsten Heimrich 13612fd6cc2SKarsten Heimrich BRect r(frame); 13712fd6cc2SKarsten Heimrich float size, max; 13812fd6cc2SKarsten Heimrich 13912fd6cc2SKarsten Heimrich r.OffsetTo(0, 0); 14012fd6cc2SKarsten Heimrich const int height = r.IntegerHeight()+1; 14112fd6cc2SKarsten Heimrich const int delta = height / 4; 14212fd6cc2SKarsten Heimrich const float red_top = 0; 14312fd6cc2SKarsten Heimrich const float green_top = delta; 14412fd6cc2SKarsten Heimrich const float blue_top = green_top + delta; 14512fd6cc2SKarsten Heimrich const float gray_top = r.bottom - delta; 14612fd6cc2SKarsten Heimrich 14712fd6cc2SKarsten Heimrich const char* kRedLabel = "Red: "; 14812fd6cc2SKarsten Heimrich const char* kGreenLabel = "Green: "; 14912fd6cc2SKarsten Heimrich const char* kBlueLabel = "Blue: "; 15012fd6cc2SKarsten Heimrich const char* kGrayLabel = "Black: "; 15112fd6cc2SKarsten Heimrich 15212fd6cc2SKarsten Heimrich 15312fd6cc2SKarsten Heimrich BFont font(be_plain_font); 15412fd6cc2SKarsten Heimrich font_height fh; 15512fd6cc2SKarsten Heimrich font.GetHeight(&fh); 15612fd6cc2SKarsten Heimrich 15712fd6cc2SKarsten Heimrich max = size = font.StringWidth(kRedLabel); 15812fd6cc2SKarsten Heimrich r.Set(0, 0, size, fh.ascent + fh.descent); 15912fd6cc2SKarsten Heimrich r.OffsetTo(0, red_top); 16012fd6cc2SKarsten Heimrich r.right = r.left + size; 16112fd6cc2SKarsten Heimrich AddChild(new BStringView(r, "red", kRedLabel)); 16212fd6cc2SKarsten Heimrich 16312fd6cc2SKarsten Heimrich size = font.StringWidth(kGreenLabel); 16412fd6cc2SKarsten Heimrich r.Set(0, 0, size, fh.ascent + fh.descent); 16512fd6cc2SKarsten Heimrich if (max < size) max = size; 16612fd6cc2SKarsten Heimrich r.OffsetTo(0, green_top); 16712fd6cc2SKarsten Heimrich r.right = r.left + size; 16812fd6cc2SKarsten Heimrich AddChild(new BStringView(r, "green", kGreenLabel)); 16912fd6cc2SKarsten Heimrich 17012fd6cc2SKarsten Heimrich size = font.StringWidth(kBlueLabel); 17112fd6cc2SKarsten Heimrich r.Set(0, 0, size, fh.ascent + fh.descent); 17212fd6cc2SKarsten Heimrich if (max < size) max = size; 17312fd6cc2SKarsten Heimrich r.OffsetTo(0, blue_top); 17412fd6cc2SKarsten Heimrich r.right = r.left + size; 17512fd6cc2SKarsten Heimrich AddChild(new BStringView(r, "blue", kBlueLabel)); 17612fd6cc2SKarsten Heimrich 17712fd6cc2SKarsten Heimrich size = font.StringWidth(kGrayLabel); 17812fd6cc2SKarsten Heimrich r.Set(0, 0, size, fh.ascent + fh.descent); 17912fd6cc2SKarsten Heimrich if (max < size) max = size; 18012fd6cc2SKarsten Heimrich r.OffsetTo(0, gray_top); 18112fd6cc2SKarsten Heimrich r.right = r.left + size; 18212fd6cc2SKarsten Heimrich AddChild(new BStringView(r, "gray", kGrayLabel)); 18312fd6cc2SKarsten Heimrich 18412fd6cc2SKarsten Heimrich r = frame; 18512fd6cc2SKarsten Heimrich r.OffsetTo(max, 0); 18612fd6cc2SKarsten Heimrich r.right -= max; 18712fd6cc2SKarsten Heimrich fPreview = new HalftonePreviewView(r, "preview", resizeMask, flags); 18812fd6cc2SKarsten Heimrich AddChild(fPreview); 18912fd6cc2SKarsten Heimrich } 19012fd6cc2SKarsten Heimrich 191*4410ee12SMichael Pfeiffer 192*4410ee12SMichael Pfeiffer void 193*4410ee12SMichael Pfeiffer HalftoneView::Preview(float gamma, float min, 194*4410ee12SMichael Pfeiffer Halftone::DitherType ditherType, bool color) 19512fd6cc2SKarsten Heimrich { 196*4410ee12SMichael Pfeiffer fPreview->Preview(gamma, min, ditherType, color); 19712fd6cc2SKarsten Heimrich } 198