xref: /haiku/src/libs/print/libprint/HalftoneView.cpp (revision 4410ee1269f6a039e1c1060feb105ce40c8152dc)
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